Nochmal zu meinem Problem
-
Hi,
hier noch mal mein Problem, der alte Thread war wohl etwas zugemüllt
Also, ich habe eine Memberfunktion in einer DLL:
// Klassenname usw. sind egal, die sind nur, weil ich jetzt grade kopier, damit ich net den Fehler rausschneid :) void CScriptLanguageMgr::UnregisterScriptLanguage(const CString &strName) { // Alles auskommentiert throw 1; }
Diese Funktion wird jetzt in meiner EXE ganz normal aufgerufen (die DLL ist statisch zu der EXE gelinkt, falls das was zur Sache tut):
try { (pKernel->GetScriptLanguageMgr()).UnregisterScriptLanguage("a"); } catch (...) { MessageBox(NULL, "Exception", "Error", MB_ICONERROR | MB_OK); }
Mein Problem ist jetzt, dass ich erst einige Debug Assertions kriege (2 Stück, wenn ich immer auf Ignorieren drücke), dann kommt die MessageBox() und dann nochmal eine Schutzverletzung.
Wenn ich die Laufzeitbibliothek im Visual C++ auf Multithreaded DLL stelle, geht es, aber grade bei diesem Projekt will ich keinen gemeinsamen Heap!
Es liegt an CString (anderswo hat mich mal behauptet, mit std::string käme das gleiche Problem, aber das stimmt doch nicht). CString sieht so aus:
class CString : public std::string { public: AGEAPI CString(const std::string &strString); AGEAPI CString(const char *pchString); AGEAPI CString(int nNumber); private: static AGEAPI CString IntToString(int nNumber); };
Wenn ich den Parameter von UnregisterScriptLanguage() entferne oder durch ein std::string ersetze, geht alles.
Bitte helft mir!
ChrisM
PS: Net wundern wegen throw 1; normalerweise werfe ich eine Exceptionklasse, der int ist nur zum Sicherstellen, dass es nicht an der Exceptionklasse liegt!
-
Welches OS und welchen Compiler verwendest Du ?
Standard C++ kennt keine DLL
-
Windows XP und Visual C++ 6.0 Standard.
Bitte trotzdem net verschieben, ich denk es hängt irgendwie damit zusammen, dass die CString-Instanz falsch gelöscht wird oder so, weil bei gemeinsamen Heap von EXE & DLL (d.h. ich kann vom jeweils anderen Teil Objekte vom Heap löschen) kein Fehler kommt.
Bitte helft mir! Es muss quasi an CString liegen.
ChrisM
-
Warum erbt die Klasse von std::string? Mach notfalls ein std::string-Member, aber zum wild Herumerben sind die Standard-Klassen nicht gedacht.
-
Damit ich alle Features von std::string habe, aber trotzdem noch weitere hinzufügen kann, wie z.B. die IntToString()-Funktion.
Das einzigste Problem das sein könnte, wäre, dass der std::string-Destruktor nicht virtuell ist, aber der wird ja nirgends aufgerufen, weil überall explizit CString steht und außerdem hat CString ja keine eigenen Members für die sich ein Destruktor lohnen würde.ChrisM
-
Der std::string-Destruktor muss natürlich aufgerufen werden, das ist nunmal so wenn Du von einer Klasse erbst.
[ Dieser Beitrag wurde am 21.04.2003 um 00:19 Uhr von nman editiert. ]
-
Wie der muss aufgerufen werden? Ich denk, wenn meine abgeleitete Klasse keinen Destruktor implementiert, wird automatisch der von der Basisklasse aufgerufen, oder?
Und selbst wenn, dann dürfte doch keine Debug Assertion Failed kommen, höchstens ein Memory Leak, oder?
ChrisM
-
... dann wird automatisch ein destruktor gemacht, der den basisklassendtor aufruft.
du darfst nur nirgends nach std::string casten und das dann löschen. dann müsste der basic_string dtor virtuell sein.
also wenn du nur mit CString arbeitest, dann wird immer der dtor von basic_string aufgerufen werden (wenn du bei nicht-auto variablen immer brav delete-st)
-
-
@davie: Wie du ja am Code oben siehst, verwende ich nirgends std::string, sondern durchgehend CString. Ich versteh das einfach nicht.
ChrisM
PS: Den Link les ich mir gleich mal durch, aber jetzt frühstück ich erstmal
-
Ich glaub, ich probiere jetzt mal STLport aus, mit der gehts evtl.
Weiß jemand, wo ich STLport vorkompiliert für VC6 herkriege, weil ich nicht nmake'n kann, weil ich dummerweise keine Environment Variablen habe setzen lassen (bei der Installation von VC6)?ChrisM
-
schonmal was von absoluten pfadangaben gehört?
naja, egal.
das problem kann nicht an CString liegen - denn das einzige was sein kann ist, dass ein memory leak entsteht - aber sicher kein undefiniertes verhalten.ich nehme an, das problem liegt bei der übergabe der exception von der dll in die exe -> soweit ich weiß, ist soetwas böse. da eine exception in der dll eine andere signatur haben kann als in der exe.
wirf mal eine exception in der exe und fang sie in der exe - ich wette es wird alles gut gehen.
also ab damit in VC++ Forum
-
Nein, es geht auch in der EXE nicht.
void Test(const CString &String) { throw 1; } try { ::Test("Hallo"); } catch (...) { MessageBox(NULL, "Unknown exception occured!", "Error", MB_ICONERROR | MB_OK); } // Hierher kommt das Programm nicht ohne die Debug Assertion!
Der Debugger zeigt an:
HEAP[Techdemo.exe]: Invalid Address specified to RtlValidateHeap( 00970000, 008600E0 )
Nicht abgefangene Ausnahme in Techdemo.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.Mögliche Erklärung, weiß aber nicht, ob sie stimmt: Die EXE erstellt das Objekt auf ihrem Heap, aber die DLL versucht es zu löschen, weil CString in der DLL implementiert ist. Da die Heaps getrennt sind, kommt dann die Assertion.
Ich frag mich nur, warum nicht versucht wird, dass ganze von der EXE löschen zu lassen, ich hab ja in der DLL keinen Destruktor explizit erstellt.ChrisM
-
*heul*
Das kann doch net, verwend ich halt doch Multithreaded DLL Laufzeitbibliothek.
Nur noch eine Frage, unter VC wird bei Multithreaded DLL ja die Standardbibliothek nicht direkt zur EXE gelinkt, sondern zur Laufzeit aus msvcrt.dll (Microsoft Visual C++ Runtime oder so).
Die Frage ist nur, gibts sowas auch unter Linux, weil wenn nur wegen so einem Problem mein Programm nicht mehr unter Linux geht, wär das extrem ärgerlich!! (vielleicht dann als gccrt.so oder so ähnlich)
ChrisM
-
weg damit ins Linux Forum
-
Kein Problem, ich frag dort nach
ChrisM
-
Original erstellt von ChrisM:
**Nein, es geht auch in der EXE nicht.void Test(const CString &String) { throw 1; } try { ::Test("Hallo"); } catch (...) { MessageBox(NULL, "Unknown exception occured!", "Error", MB_ICONERROR | MB_OK); } // Hierher kommt das Programm nicht ohne die Debug Assertion!
ChrisM**
Kann es sein das die Exceptions ( (/EHsc) ) garnicht an sind ?
-
Doch, sind in den Compilereinstellungen aktiviert.
Außerdem gehts ja ohne den CString-Parameter einwandfrei.
ChrisM
-
Mach mal ein minimalbeispiel bei Dir (Win32 App und bau die Zeilen von oben ein) fliegt Dir hier immer noch eine Exception um die Ohren ?
Das Problem scheint mir in der Methode zu sein die den CString bekommt.
Gruß
Michael
-
Mach ich, dauert aber noch etwas.
ChrisM