Ich habe eine C++/CLI gemischte DLL erstellt, die ich von einer C# Winforms-Anwendung aus verwende. Ich habe die Build-Konfiguration sorgfältig überprüft, um sicherzustellen, dass ich in Debug-Modus mit Debug-Bibliotheken und in Release-Modus mit nicht-Debug-Bibliotheken verlinke.
Bisher macht die Anwendung nichts, erstellt nur eine native Klasse in einem verwalteten Wrapper wie folgt (Singleton-Muster, um eine einzige Instanz der Klasse sicherzustellen):
static ManagedClassWrapper ^ GetInstance(){
if(_me == nullptr){
_me = gcnew ManagedClassWrapper();
_me->_Impl = new NativeClass();
}
return _me;
};
wo _me und _impl sind
private:
NativeClass * _Impl;
static ManagedClassWrapper ^ _me = nullptr;
In dem Formular klicke ich auf einen Button und mache einfach das:
private void button1_Click(object sender, EventArgs e)
{
ManagedClassWrapper mcw = ManagedClassWrapper.GetInstance();
}
Ich habe auch einen standardmäßigen nativen Einstiegspunkt wie üblich in DllMain. Im DEBUG-Build verwende ich
_CrtSetReportHook( QaDMemManager::report );
_CrtSetDbgFlag((_CRTDBG_LEAK_CHECK_DF) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
am Anfang von DllMain, und im DEBUG-Build habe ich auch `new` neu definiert:
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#define LOG_LEVEL Logger::NOTICE
#include
#include
#pragma warning(disable:4291)
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#else
#define LOG_LEVEL Logger::INFO
#endif
wie ich es normalerweise für meine non-MFC-Apps mache, um einen schönen Speicherleck zu bekommen.
Der Konstruktor von NativeClass ist leer.
Alles funktioniert gut in Debug-Builds, ich sehe Speicherlecks im nativen Code, keine Abstürze.
Aber im Release-Build stürzt meine App gelegentlich ab, wenn ich auf den Button1 klicke. Das bedeutet: Ich kann 10 Instanzen meiner App starten, 9 werden gut funktionieren, egal wie oft ich auf Button1 klicke, aber die 10. wird jedes Mal abstürzen, wenn ich auf Button1 klicke (nach dem Absturz klicke ich in dem Ausnahmefenster auf Weiter, und dann kann ich mehrmals auf Button1 klicken).
Die Ausnahme ist folgende:
************** Exception Text **************
System.TypeInitializationException: Der Typeninitialisierer für '' hat eine Ausnahme ausgelöst. ---> System.AccessViolationException: Versuch, geschützten Speicher zu lesen oder zu beschreiben. Dies deutet oft darauf hin, dass anderer Speicher beschädigt ist.
at _initterm((fnptr)* pfbegin, (fnptr)* pfend)
at .LanguageSupport.InitializeNative(LanguageSupport* )
at .LanguageSupport._Initialize(LanguageSupport* )
at .LanguageSupport.Initialize(LanguageSupport* )
at .cctor()
--- Ende der internen Ausnahmestapelüberwachung ---
at TestAudioInOut.TestForm.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
TestAudioInOut
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///V:/Test/bin/Release/Test.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
Mixed.DLL
Assembly Version: 1.0.4026.39493
Win32 Version:
CodeBase: file:///V:/Test/bin/Release/Mixed.DLL
----------------------------------------
Was könnte das Problem sein (wie ich verstehe, bedeutet TypeInitializationException, dass etwas mit dem Aufbau von Objekten nicht stimmt) und warum tritt es nur im Release-Modus auf?