Probleme bei DestroyWindow in einer DLL
-
Hiho,
ich habe hier einen Quellcode zur Fehlerbereinigung. Das meiste ist auch schon raus, aber eine Sache bereitet mir gerade Kopfzerbrechen.
In einer DLL wird ein CFrameWnd angelegt (mit new). Im späteren Verlauf wird das Fenster mit DestroyWindow zerstört. Und das löst irgendetwas aus.Das Hauptprogamm ist ein Konsolenprogramm mit MFC-Unterstützung. Die main wird abgearbeitet. Nach dem Verlassen der main fliegt irgendwann folgender Fehler:
Windows hat einen Haltepunkt in test.exe ausgelöst.
Dies kann auf eine Beschädigung des Heaps zurückzuführen sein und weist auf ein Problem in test.exe oder in einer der geladenen DLLs hin.
Weitere Analyseinformationen finden Sie möglicherweise im Ausgabefenster.
Wenn ich nun in der DLL das DestroyWindow rausnehme, fliegt der Fehler nicht.
DLL wie auch Programm nutzen beide MFC in einer öffentlichen DLL. Die DLL wurde als MFC-Erweiterungs-DLL angelegt. Es werden keine Funktionen direkt exportiert sonderb 1 Klasse mit AFX_EXT_CLASS für das Nutzerprogramm zugänglich gemacht.Irgendwie beim Entladen der DLL geht etwas schief: folgende Zeile in der dllinit.cpp hat damit zu tun:
// free any local data for this process/thread AfxTermLocalData(NULL, TRUE);Irgendwie sind mir die Ideen ausgegangen, woran es liegen könnte. Irgednwelche Compiler-Schalter falsch oder sonst irgend etwas anderes?
MfG Pellaeon
-
Du darfst die DLL natürlich nicht entladen bevor nicht alle Fenster, die dieses DLL bedient auch zerstört sind.
Was sagt den der Callstack wo es knallt.
-
Hallo Martin,
das Programm wird gegen die lib der dll gelinkt. Ein dynamisches Laden/Entladen erfolgt also nicht.
Hier ist wie gebeten ein Auszug aus der Aufrufliste:
ntdll.dll!771c7dfe()
mehrmals ntdll.dll!77231c93()
> msvcr80d.dll!_free_base(void * pBlock=0x02378c58) Zeile 109 + 0x13 Bytes C
msvcr80d.dll!_free_dbg_nolock(void * pUserData=0x02378c78, int nBlockUse=1) Zeile 1346 + 0x9 Bytes C++
msvcr80d.dll!_free_dbg(void * pUserData=0x02378c78, int nBlockUse=1) Zeile 1220 + 0xd Bytes C++
mfc80d.dll!operator delete(void * p=0x02378c78) Zeile 373 + 0xc Bytes C++
mfc80d.dll!CHandleMap::scalar deleting destructor'() + 0x20 Bytes C++ mfc80d.dll!AFX\_MODULE\_THREAD\_STATE::~AFX\_MODULE\_THREAD\_STATE() Zeile 366 + 0x1f Bytes C++ mfc80d.dll!AFX\_MODULE\_THREAD_STATE::scalar deleting destructor'() + 0xf Bytes C++
mfc80d.dll!CThreadSlotData::DeleteValues(CThreadData * pData=0x0019d7a0, HINSTANCE__ * hInst=0x00000000) Zeile 353 + 0x29 Bytes C++
mfc80d.dll!CThreadSlotData::DeleteValues(HINSTANCE__ * hInst=0x00000000, int bAll=1) Zeile 395 C++
mfc80d.dll!AfxTermLocalData(HINSTANCE__ * hInst=0x00000000, int bAll=1) Zeile 493 C++
mfc80d.dll!DllMain(HINSTANCE__ * hInstance=0x6aea0000, unsigned long dwReason=0, void * __formal=0x00000001) Zeile 563 + 0x9 Bytes C++
mfc80d.dll!__DllMainCRTStartup(void * hDllHandle=0x6aea0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Zeile 498 + 0x11 Bytes C
mfc80d.dll!_DllMainCRTStartup(void * hDllHandle=0x6aea0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Zeile 462 + 0x11 Bytes C
ntdll.dll!771be1c4()
ntdll.dll!771aa8dd()
ntdll.dll!771e921a()
ntdll.dll!771aa8be()
ntdll.dll!771aa85f()
kernel32.dll!768c3b69()
msvcr80d.dll!__crtExitProcess(int status=0) Zeile 684 C
msvcr80d.dll!doexit(int code=0, int quick=0, int retcaller=0) Zeile 596 + 0x9 Bytes C
msvcr80d.dll!exit(int code=0) Zeile 398 + 0xd Bytes C
test.exe!__tmainCRTStartup() Zeile 610 C
test.exe!mainCRTStartup() Zeile 414 C
-
Ein Konsolen Programm und darin erzeugst Du Fenster. Das geht zwar ist aber doch ziemlich abstrus.
Offensichtlich wird die DLL entladen und es sind noch Objekte aktiv.
Was ist das für eine DLL?
Extension DLL oder Standard DLL?Mal eine ganz andere Frage. Warum diese koische Konstruktion?
-
Martin Richter schrieb:
Ein Konsolen Programm und darin erzeugst Du Fenster. Das geht zwar ist aber doch ziemlich abstrus.
Offensichtlich wird die DLL entladen und es sind noch Objekte aktiv.
Was ist das für eine DLL?
Extension DLL oder Standard DLL?Eine MFC-Erweiterungs-DLL
Martin Richter schrieb:
Mal eine ganz andere Frage. Warum diese koische Konstruktion?
War nicht meine Idee^^
Das ist eine GKS-Nachbildung (Grafikkern System) für den Lehrbetrieb. Ich hab nur den Source bekommen und suche jetzt Fehler.
Hm meinst du in einer normalen Win-Anwendung, also nicht Konsole. würde es gehen?Also das Problem tritt anscheinend dann auf, wenn ich den Destruktor des CFrameWnd aufrufe. Nehme ich das DestroyWindow raus und mache per Hand delete (ich weiß, nicht der richtige Weg, aber ich teste einfach rum, um den Fehler zu finden), dann fliegt die Fehlermeldung auch.
Das Fenster selber ist wirklich nur ein CFrameWnd in das dann mit OpenGL reingerendert wird.Jetzt den ganzen Quellcode reinkopieren bringt sicher auch nix.
Was für Objekte könnten denn da noch aktiv sein? Irgendeine Richtung in der ich suchen kann?Ansonsten erstmal danke für deine Hilfe
Ich rätsel dann morgen weiter^^MfG Pellaeon
-
Eine Extension DLL kann Imho nur dann korrekt funktionieren, wenn sie komplett in eine Windows MFC Anwendung eingebunden ist. Das Problem ist schon das CWinApp, dass diese Applikation benötigt. Wie das wirklich und ob das wirklich mit einem Consolen Programm funktioniert weiß ich nicht.
Nach meinem Dafürhalten ist der Konstrukt absoluter Unsinn!
Warum eine Konsole erzeugen und dann noch weitere Fenster.Die Ursache liegt mit Sicherheit darin, dass noch Objekte existieren, die in der DLL angelegt wurden und die nun nicht freigegeben werden können.
Wir mit atexit irgwendwas registriert?
-
Bevor du mir was an den Kopf schmeißen willst: ich habs net gebaut, bitte im Hinterkopf behalten

Es wird DestroyWindow aufgerufen und an späterer Stelle noch mit dem Fensterobjekt gearbeitet. Es wird nur auf eine int-Variable zugegriffen. Naja aber dadurch, dass DestroyWindow ein delete this; macht ... . Mich wundert es, dass das überhaupt mal lief. Der int-Wert wird nur auf 0 gesetzt, aber anscheinend an einer ungünstigen Adresse ... .
Na egal, nochmal danke für deine Bemühungen!