2010-11-22 7 views
0

Nach Using Rich Edit Controls ich RichEdit in einer solchen Art und Weise verwenden:Absturz nach dem zweiten RichEdit Initialisierung in x64

MyControl::OnCreate() 
{ 
    handle = LoadLibrary(_T("Riched20.dll")); 
} 

MyControl::OnDestroy() 
{ 
    FreeLibrary(handle); 
} 

Es funktioniert für win32 in Ordnung, aber vor kurzem habe ich x64-Konfiguration gebaut und jetzt nicht meiner Kontrolle nach dem Neuladen der Seite .

alt text

Ich habe bemerkt, dass, wenn dies zu tun:

MyControl::OnCreate() 
{ 
    handle = LoadLibrary(_T("Riched20.dll")); 
    FreeLibrary(handle); 
    handle = LoadLibrary(_T("Riched20.dll")); 
} 

alles funktioniert.

Ich möchte diesen Code nicht in Produktion bringen, gibt es also Vorschläge für eine bessere Lösung/Workaround?

Antwort

3

Da das gemeldete Fehlermodul Richedit20.dll_unloaded ist, bedeutet dies, dass Sie die DLL entladen, während der Code noch verwendet wird.

Zum Beispiel, wenn Sie noch ein Richedit-Fenster geöffnet haben, wenn Sie (vollständig) die DLL freigeben, können Sie solche Abstürze sehen, sobald irgendetwas einen Aufruf des Fensters proc auslöst. Dies liegt daran, dass sich das Fenster-Proc des Steuerelements innerhalb des entladenen DLL-Codes befand.

Es sollte sicher sein, LoadLibrary und FreeLibrary mehrere Male (solange die Anrufe ausgleichen), so dass ich bezweifle, dass das Problem ist. Es kann nur das Problem auslösen. Außerdem gab es das Problem in 32-Bit-Builds; Du hast nur Glück gehabt und es nie ausgelöst.

OnDestroy ist der falsche Ort, um FreeLibrary aufzurufen. Es gibt mehrere Fenstermeldungen, die nach WM_DESTROY (z. B. WM_NCDESTROY) in ein Fenster gesendet werden.

Untergeordnete Fenster sind auch noch vorhanden, wenn OnDestroy aufgerufen wird. Wenn die Richedits Kinder Ihrer Kontrolle sind (und nicht das Steuerelement selbst), können Sie die FreeLibrary in OnNcDestroy speichern. (Untergeordnete Fenster werden zu dem Zeitpunkt zerstört, zu dem WM_NCDESTROY aufgerufen wird.) Ich würde dennoch sagen, dass es kein guter Ort ist, um die Bibliothek zu befreien.

Sie möchten also unbedingt Ihren FreeLibrary-Anruf verschieben. Ich würde sowohl es als auch die LoadLibrary komplett außer Kontrolle bringen. Es ist nicht normal, über Steuerelemente zu verfügen, die Bibliotheken laden/freigeben, wenn eine Instanz von ihnen erstellt wird. Stattdessen muss irgendwo ein statischer Init/Uninit-Code vorhanden sein, der die benötigten Bibliotheken ein für allemal lädt und sie freigibt, wenn die Anwendung heruntergefahren wird.

(Wenn Ihre App nur selten das Steuerelement verwendet, kann es sinnvoll sein, die Bibliothek nur zu laden/freizugeben, wenn Fenster mit dem Steuerelement aktiv sind. Diese Situation ist jedoch selten. Normalerweise ist es besser, die DLL zu verlassen geladen.)

+0

Vielen Dank für eine schnelle Antwort. Ich habe den Code zu DllMain verschoben und alles funktioniert jetzt gut. Danke noch einmal. – Eugene

+1

@Eugene Glücklich zu helfen! BTW, LoadLibrary in DllMain aufrufen, kann auch Probleme verursachen. Sehen Sie hier: http://blogs.msdn.com/b/larryosterman/archive/2004/04/23/118979.aspx - Idealerweise würden Sie diesen Code in eine Init-Funktion Ihrer DLL setzen, die die übergeordnete Anwendung nach dem Laden aufruft Ihre DLL. (Dies ist auch der richtige Ort, um die Fensterklasse des Steuerelements zu registrieren.) Wenn Sie keine Kontrolle über die Hauptanwendung haben, kann es jedoch schwierig werden. :( –

Verwandte Themen