C++ Exceptions verlassen nicht die DLL?
-
Ich habe bisher nur statische C++-Libraries entwickelt, und da klappt das werfen von C++ Exceptions und diese schlagen auch bis zum Client-Code durch.
Jetzt habe ich mal eine DLL erstellt. Ich kann problemlos exportierte C++ Klassen bzw. Objekte im Client-Code (EXE) nutzen. Soweit so gut.
1. Wenn ich aber in der DLL eine C++ Exception werfe, schlägt sie nicht bis zum Client-Code durch. Sie verpufft anscheinend an der DLL-Grenze? Innerhalb der DLL kann ich sie auch abfangen.
Wenn ich sie nicht abfange, geht sie anscheinend verloren, sprich: First-Chance-Excetion erscheint, aber Unhandled Exception bekomme ich merkwürdigerweise nicht!2. Wenn ich von einer DLL-Klasse erbe, also im Client-Code eine neue Klasse definiere, die von einer exportierten Klasse erbt, wird auch aus dieser Klasse die Exception nicht weiter geworfen. OK, klingt logisch, wenn Fall 1 zutrifft und die Ist-Ein-Beziehung greift hier.
3. Wenn ich im Client-Code eine nicht exportiere Klasse habe und darin eine Exception werfe, funktioniert alles wie erwartet, die Exception schlägt bis zur Main durch. Sprich First-Chance-Exception und dann Unhandled Exception.
Was habe ich falsch gemacht, dass die C++ Exceptions nicht bis zur EXE durch schlagen?
Anmerkung: die DLL und EXE sind in der selben Solution, benutzen die selbe CRT-DLL. Und ich benutze keine unterschiedlichen Compiler oder Compiler Versionen. Alles in einer VS2013-Solution.
-
Hallo Artchi,
C++ Exceptions über DLL-Grenzen hinweg ist ein schwieriges Thema (eigentlich sollte es bei gleicher Laufzeitumgebung aber funktionieren, s. z.B. Throwing C++ exceptions across DLL boundaries).
Eine mögliche Lösung unter Windows ist SEH, s.a. Effective Exception Handling in Visual C++.
-
Das ist seltsam.
Wir verwenden MSCV (wenn auch eine ältere Version) und werfen *andauernd* Exceptions über DLL-Grenzen. Funktioniert komplett und total problemlos.Bloss bei
extern "C"
Funktionen muss man aufpassen, da der Compiler bei diesen automatisch annimmt dass sie keine C++ Exceptions werfen können, und daher keinen Code generiert um rausfliegende Exceptions zu behandeln.Welche CRT und Exception-Handling Einstellungen verwendet ihr denn für die Projekte?
ps: Default sollte
/EHsc
sein. Das wäre die "C++ Exceptions fangen und davon ausgehen dassextern "C"
nix wirft" Einstellung./EHs
ist das selbe ohne die Spezialbehandlung vonextern "C"
Funktionen (=> etwas langsamer).
/EHa
wird wenig verwendet, ist nur nötig wenn man allgemeine SEH Exceptions fangen will, also z.B. sowas was vom OS generiert wird wenn man ne Access-Violation macht.
-
hustbaer schrieb:
Das ist seltsam.
Wir verwenden MSCV (wenn auch eine ältere Version) und werfen *andauernd* Exceptions über DLL-Grenzen. Funktioniert komplett und total problemlos.Das "Problem" ist, dass die Standards für C und C++ keine Binärkompatibilität zwischen verschiedenen Compilern bzw. Compiler-Versionen garantieren.
Einfaches Beispiel: Es wird zwar im C Standard festgelegt, dass**
fopen()
einenFILE*
Pointer zurück liefert und dass ich einen solchenFILE*
Pointer wieder an Funktionen wiefwrite()
undfread()
übergeben kann. Aber wie dasFILE
struct konkret aussieht, bleibt allein dem Compiler überlassen! Im C-Standard ist es einfach nicht definiert und man sollte daher nie direkt auf einFILE
struct zugreifen. Aus dem selben Grund kann es gewaltig krachen, wenn ich eine Datei in Modul "A" öffne und denFILE*
**Pointer zur weiteren Verwendung an Modul "B" übergebe - sofern nicht beide Module mit dem selben Compiler übersetzt wurden. Wenn es trotzdem klappt, Glück gehabt! Aber "sicher" ist es eben nicht.Bei Exceptions ist es ähnlich. Es wird im C++ Standard definiert, wie Exceptions zu funktionieren haben. Aber eben nicht, wie der Compiler diese Funktion exakt umzusetzen hat. Aus diesem Grund klappt das Übergeben von C++ Exceptions über Modul-Grenzen hinweg nur dann zuverlässig, wenn alle Module "auf dem Weg" mit dem selben Compiler bzw. der selben Compiler-Version gebaut wurden. Das das Modul, wo die Exception auftritt, und das Modul, wo sie "gefangen" werden soll, mit dem selben Compiler übersetzt wurden, reicht übrigens noch nicht! Schon wenn Dein Call-Stack an irgend einer Stelle durch ein "fremdes" Modul verläuft, kann es Probleme geben - das ist häufig bei Callbacks und ähnlichem der Fall. Daher sollte man Exceptions nur dann über Modul-Grenzen übergeben, wenn man sich sicher ist, dass da wirklich kein "fremdes" Modul im Spiel sein könnte.
Generell würde ich empfehlen alle Exceptions spätestens in der Funktion, die Deine DLL "nach außen" exportiert, abzufangen und im Fehlerfall lieber sinnvolle Fehler-Codes über die DLL-Schnittstelle zurück zu liefern.
-
DeathCubeUK schrieb:
hustbaer schrieb:
Das ist seltsam.
Wir verwenden MSCV (wenn auch eine ältere Version) und werfen *andauernd* Exceptions über DLL-Grenzen. Funktioniert komplett und total problemlos.Das "Problem" ist, dass die Standards für C und C++ keine Binärkompatibilität zwischen verschiedenen Compilern bzw. Compiler-Versionen garantieren.
Richtig. Ist mir bekannt. Der OP hat aber alles mit einem Compiler übersetzt. Die Frage ist dann nur mehr ob dieser Compiler es unterstützt Exceptions über DLL-Grenzen hinweg zu werfen. Und MSVC unterstützt das - die diverse MSVC Libraries machen davon auch selbst gebrauch.
DeathCubeUK schrieb:
Bei Exceptions ist es ähnlich. Es wird im C++ Standard definiert (...) Schon wenn Dein Call-Stack an irgend einer Stelle durch ein "fremdes" Modul verläuft, kann es Probleme geben - das ist häufig bei Callbacks und ähnlichem der Fall. Daher sollte man Exceptions nur dann über Modul-Grenzen übergeben, wenn man sich sicher ist, dass da wirklich kein "fremdes" Modul im Spiel sein könnte.
Zum Teil richtig. MSVC baut sein C++ Exception Handling auf SEH auf, was ein Windows-Standard ist. Diverse Usermode DLLs sind auch "passend" übersetzt, so dass man auch C++ Exceptions "durch" Windows DLLs durch werfen kann. Ich weiss nicht inwieweit von Windows garantiert wird dass Windows DLLs in dem Sinn Exception-safe sind dass dabei passend "aufgeräumt" wird. Damit das funktioniert müssen ja überall entsprechende
__try/__finally
Blöcke für den Cleanup-Code vorhanden sein. Aber erfahrungsgemäss funktioniert es.DeathCubeUK schrieb:
Generell würde ich empfehlen alle Exceptions spätestens in der Funktion, die Deine DLL "nach außen" exportiert, abzufangen und im Fehlerfall lieber sinnvolle Fehler-Codes über die DLL-Schnittstelle zurück zu liefern.
Das sollte man so machen wenn man DLLs schreibt die von fremdem Code verwendet werden können sollen bzw. müssen. Wenn man allerdings nur DLLs verwendet um seinen eigenen Code besser zu strukturieren/aufzuteilen - z.B. damit man bei einem inkrementellen Build nicht immer alles neu linken muss, und eben einen Compiler verwendet der das unterstützt - dann ist das kein Thema.
-
hustbaer und Th69! Folgende Parameter beim Debug Config für alle Projekte: /EHsc /MDd
Im Output, wenn die Exe startet, sieht man auch das er die entsprechenden CRT-DLLs lädt.Vielleicht liegt es auch am Export? Alle meine Klassen haben folgendes Makro:
#ifdef CYAN_EXPORTS #define CYAN_API __declspec(dllexport) #else #define CYAN_API __declspec(dllimport) #endif class CYAN_API MyClass { ... };
Wenn ich Exceptions werfe, dann die von std::exception geerbten. Ich habe auch auch schon ohne Erfolg versucht einfach plain int zu werfen, also
throw int(1);
Oder kann man nur eigene dllexportierte Klassen werfen? Wobei ja eigentlich die std-Klassen DLL-fähig sind?
Oder hat die dllmain() etwas damit zu tun? Die sieht so aus (ist vom VC-Projekt autom. generiert worden):
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
DeathCubeUK! Bitte erstmal mein Posting lesen, bevor du mit Standard-Antworten kommst. Deshalb hatte ich in meinem Posting die "Anmerkung" mit gegeben, weil ich deinen "Rat" schon tausendfach im Internet gefunden habe, wenn ich die Begriffe "C++ Exception DLL" in meine bevorzugte Suchmaschine eingebe. Weil überall wird nur abgeraten, selbst wenn die Poster deutlich schreiben, das sie eigene interne DLL-Projekte haben. So weit war ich also auch schon.
-
SEH und C++ Exceptions sind ja erstmal zwei völlig unterschiedliche Dinge. SEH ist Funktion der Win32 API, dementsprechend ausschließlich in Windows verfügbar und nicht an eine bestimmte Sprache Gebunden. In C/C++ kann man SEH über die proprietären Erweiterungen**
__try
and__except
**verwenden - zumindest wenn man ausschließlich für Windows entwickelt und ausschließlich den Microsoft Compiler verwendet. C++ Exceptions hingegen sind ein Sprach-Feature von C++ und daher unter allen Compilern auf allen Plattformen verfügbar. Microsoft sagt dazu selbst "Although Windows and Visual C++ support structured exception handling (SEH), we recommend that you use ISO-standard C++ exception handling because it makes code more portable and flexible."Wie der jeweilige Compiler die C++ Exceptions technisch umsetzt bleibt jedoch allein dem jeweiligen Compiler überlassen. Selbst dann, wenn der Microsoft Compiler und die Windows System DLL's so abgestimmt sind, dass C++ Exceptions aus Modulen, die mit MSVC kompiliert wurden (dass C++ Exceptions bei MSVC mittels SEH behandelt werden hab ich allerdings noch nirgendwo gehört, hast Du da eine Quelle?), problemlos "durch gepumpt" werden, hilft das ja nur sehr begrenzt! Weiterhin müssten sowohl das Modul, aus dem die Exception "geworfen" wird, als auch das Modul, wo sie "gefangen" werden soll, mit MSVC kompiliert worden sein und es darf sich keine einzige "fremde" DLL - zum Beispiel eine die mit einem aktuellen MinGW/GCC kompiliert wurde - auf dem Callstack "dazwischen" befinden. Ein aktuelles MinGW/GCC verwendet z.B. standardmäßig "Dwarf-2" Exception-Handling, was definitiv nicht mit MSVC kompatibel ist.
-
Artchi schrieb:
DeathCubeUK! Bitte erstmal mein Posting lesen, bevor du mit Standard-Antworten kommst. Deshalb hatte ich in meinem Posting die "Anmerkung" mit gegeben, weil ich deinen "Rat" schon tausendfach im Internet gefunden habe, wenn ich die Begriffe "C++ Exception DLL" in meine bevorzugte Suchmaschine eingebe. Weil überall wird nur abgeraten, selbst wenn die Poster deutlich schreiben, das sie eigene interne DLL-Projekte haben. So weit war ich also auch schon.
Wie in meinem Post beschrieben, ist für die "sichere" Übergabe von Exceptions von einem Modul A zu einem anderen Modul B zwar eine notwendige Voraussetzung, dass beide Module mit dem selben C++ Compiler übersetzt wurden und dass beide Module die selbe CRT-DLL benutzen - das alleine ist eben aber noch nicht ausreichend, weil es da noch mehr Fallstricke gibt!
-
Freund DeathCubeUK...
dass C++ Exceptions bei MSVC mittels SEH behandelt werden hab ich allerdings noch nirgendwo gehört, hast Du da eine Quelle?
Steht z.B. hier im ersten Satz:
http://blogs.msdn.com/b/zhanli/archive/2010/06/25/structured-exception-handling-seh-and-c-exception-handling.aspx
Oder auch...
http://support.microsoft.com/kb/185294
http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspxDavon abgesehen, hast du wirklich den Eindruck dich besser mit dem Thema SEH und C++ Exception Handling auszukennen als ich, so dass du mich "belehren" müsstest?
-
DeathCubeUK! Schön und gut was du alles schreibst. Aber das ist absolut am Thema vorbei! Ich habe nicht das Problem, das ich falsche/kaputte Exceptions oder Abstürze oder oder bekomme. Nein, ich bekomme NICHTS!
Kannst du mir nun helfen, das ich überhaupt etwas außerhalb der DLL mitbekomme oder nicht? Wenn ich einen Absturz bekommen würde, wäre das mehr als NICHTS.
Kannst du überhaupt zu meinem Thema etwas sagen, außer das es Gefahren birgt? Die einzigen die verstanden haben, was mein Problem ist, ist Th69 und Hustbaer.
-
DeathCubeUK schrieb:
Wie in meinem Post beschrieben, ist für die "sichere" Übergabe von Exceptions von einem Modul A zu einem anderen Modul B zwar eine notwendige Voraussetzung, dass beide Module mit dem selben C++ Compiler übersetzt wurden und dass beide Module die selbe CRT-DLL benutzen - das alleine ist eben aber noch nicht ausreichend, weil es da noch mehr Fallstricke gibt!
Deine sämtlichen Beiträge hier sind total sinnlos, da du im Gegensatz zu mir keine Erfahrung mit dem Thema zu haben scheinst (und ich meine das konkrete Thema hier, also C++ Exceptions mit MSVC unter Windows!).
Was bringt es dem OP wenn du ihm schreibst "es könnte trotzdem Probleme" geben, wenn du ihm nicht konkret sagen kannst wieso/wodurch bzw. wie er diese Probleme beheben kann?Ich im Gegensatz dazu weiss dass es funktioniert. Ob es mit anderen Compiler Versionen auch funktioniert, oder unter anderen Betriebssystemen, und was GCC mit DWARF2 macht, ist alles uniniteressant.
Die Frage die noch bleibt, ist: wieso funktioniert es beim OP nicht?
-
Artchi schrieb:
hustbaer und Th69! Folgende Parameter beim Debug Config für alle Projekte: /EHsc /MDd
Das ist OK.
Ich nehme an es ist auch bei beiden Projekten die selbe Toolchain eingestellt ...?Artchi schrieb:
Vielleicht liegt es auch am Export? Alle meine Klassen haben folgendes Makro:
#ifdef CYAN_EXPORTS #define CYAN_API __declspec(dllexport) #else #define CYAN_API __declspec(dllimport) #endif class CYAN_API MyClass { ... };
Nö, völlig orthogonales Thema, völlig wurscht.
Das__declspec(dllimport)
brauchst du nichtmal wirklich. IIRC ist das nur in ein paar Sonderfällen interessant - z.B. wenn es darum geht ob inline Funktionen, WENN sie NICHT inline erweitert werden aus der DLL genommen oder im Programm nochmal neu angelegt werden.Artchi schrieb:
Wenn ich Exceptions werfe, dann die von std::exception geerbten. Ich habe auch auch schon ohne Erfolg versucht einfach plain int zu werfen, also
throw int(1);
Oder kann man nur eigene dllexportierte Klassen werfen? Wobei ja eigentlich die std-Klassen DLL-fähig sind?
Das ist alles egal, sollte alles gehen. Die Klasse muss genau genommen nichtmal exportiert werden, muss trotzdem funktionieren.
Artchi schrieb:
Oder hat die dllmain() etwas damit zu tun? Die sieht so aus (ist vom VC-Projekt autom. generiert worden): (...)
Nö, auch egal. Vor allem wenn die DllMain "leer" ist, so wie deine.
=>
Versuch mal ein neues, frisches EXE Projekt anzulegen und ein neues, frisches DLL Projekt, und dann mal den minimal nötigen Code schreiben um das zu testen. Also eine Funktion exportieren die z.B. nen std::runtime_error wirft, und die im Hauptprogramm in einem
try-catch(std::exception const&)
aufrufen.
-
hustbaer schrieb:
Deine sämtlichen Beiträge hier sinn total sinnlos
Deine Art gefällt mir überhaupt nicht! Ich schreibe hier in meiner Freizeit und ohne jegliche Bezahlung. Daher erwarte ich, dass das honoriert wird - völlig unabhängig davon, ob mein Beitrag nun sofort die perfekte Lösung liefern konnte oder nicht - und dass ich mich hier nicht noch beleidigen lassen muss. Falls irgendetwas, das ich geschrieben habe, technisch nicht 100% korrekt gewesen sein sollte (wovon ich allerdings nicht ausgehe), dann lasse ich mich gerne verbessern. Aber so gehört sich das nicht! Das ist die beste Methode, dass hier bald niemand versucht etwas beizutragen...
[quote="hustbaer"da du im Gegensatz zu mir keine Erfahrung mit dem Thema zu haben scheinst[/quote]
Mit dieser Behauptung liegst Du falsch.hustbaer schrieb:
Was bringt es dem OP wenn du ihm schreibst "es könnte trotzdem Probleme" geben, wenn du ihm nicht konkret sagen kannst wieso/wodurch bzw. wie er diese Probleme beheben kann?
Um ein Problem zu lösen, muss man zuerst einmal wissen, was das Problem ist. Oder sein könnte! Nicht wahr?
Und für manche Probleme gibt es nun mal nicht die einfache Lösung. Dann muss man sich vllt überlegen, was ein alternativer Weg sein könnte...
hustbaer schrieb:
Ich im Gegensatz dazu weiss dass es funktioniert.
Ich habe nie behauptet, dass die Übergabe von C++ Exceptions zwischen verschiedenen Modulen nicht funktionieren kann. Es müssen aber ganz bestimmte Voraussetzungen erfüllt sein (diese habe ich benannt) und es gibt diverse Fälle, in denen es eben doch nicht funktioniert (Beispiele habe ich genannt).
hustbaer schrieb:
Die Frage die noch bleibt, ist: wieso funktioniert es beim OP nicht?
Einige mögliche Ursachen, die der OP nun überprüfen kann/sollte, habe ich genannt. Das es evtl. doch ein anderes Problem sein könnte, dass noch nicht genannt wurde, habe ich nie ausgeschlossen...
-
DeathCubeUK schrieb:
hustbaer schrieb:
Deine sämtlichen Beiträge hier sinn total sinnlos
Deine Art gefällt mir überhaupt nicht!
Und die deine gefällt mir nicht. Du machst dich hier wichtig, indem du den OP und mich über Dinge belehrst die zumindest mir gut bekannt sind, aber vor allem: Dinge die bei der Fragestellung überhaupt nicht relevant sind.
Beispiel: Artchi hat von Anfang an klar gemacht, dass er alles mit dem selben Compiler übersetzt - und sogar dazugeschrieben um welchen Compiler es sich handelt. Und dann kommst du und schreibst darüber was es nicht alles für Probleme geben kann wenn man unterschiedliche Compiler verwendet. Wo macht das Sinn? Musst du mir bitte erklären.
DeathCubeUK schrieb:
Ich schreibe hier in meiner Freizeit und ohne jegliche Bezahlung.
Das ist keine Entschuldigung dafür anderen ihre Zeit zu stehlen.
Jedem kann mal ein Fehler passieren, man kann Dinge überlesen/übersehen, alles kein Problem. Daher hab' ich auch erst noch ganz sachlich/freundlich geantwortet.
Nur wenn das selbe unpassende Zeug dann wieder und wieder kommt, dann reichts halt irgendwann.DeathCubeUK schrieb:
hustbaer schrieb:
da du im Gegensatz zu mir keine Erfahrung mit dem Thema zu haben scheinst
Mit dieser Behauptung liegst Du falsch.
Naja, macht halt nicht den Eindruck.
DeathCubeUK schrieb:
(...)Einige mögliche Ursachen, die der OP nun überprüfen kann/sollte, habe ich genannt. Das es evtl. doch ein anderes Problem sein könnte, dass noch nicht genannt wurde, habe ich nie ausgeschlossen...
Bitte zitiere mir auch nur einen einzigen solchen Tip, der nicht durch Informationen die Artchi bereits davor gegeben hat irrelevant wird.
-
hustbaer schrieb:
Du machst dich hier wichtig, indem du den OP und mich über Dinge belehrst die zumindest mir gut bekannt sind, aber vor allem: Dinge die bei der Fragestellung überhaupt nicht relevant sind.
Wenn in einem Diskussions-Forum plötzlich Redebeiträge - wohlgemerkt Beiträge die sehr wohl für das diskutierte Problem relevant sind - als unerwünschte "Belehrungen" abgewatscht werden, dann verfehlt das ganze hier doch seinen Sinn! Was Du oder der OP schon wissen, das ist mir natürlich nicht bekannt. Ich kann nur Dinge erläutern, die meiner Meinung nach für die Analyse und Lösung des Problem wichtig sind, in der Hoffnung, dass es dem Thema weiter hilft!
Falls ein inhaltlich korrekter und in guter Absicht verfasster Post nicht zur sofortigen Lösung des Problems führen sollte, dann ist eine angemessene Antwort: "Danke, dass Du Dir die Zeit genommen hast, diese richtigen und wichtigen Punkte zu erläutern. Leider war mir das meiste davon schon bekannt und ich kann ausschließen, dass mein Problem auf einen dieser Punkte zurückzuführen ist." Damit ist die Sache erledigt und es kann weiter gehen. Eine angemessene Antwort ist sicher nicht "Deine sämtlichen Beiträge hier sind total sinnlos". In wie fern hilft das weiter? Wenn ich etwas "sinnlos" finde, dann derartiges Rumgestänker, wie es ständig aus Deiner Richtung kommt. Sprichst Du im "wahren Leben" etwa auch so mit Deinen Kollegen?
hustbaer schrieb:
Das ist keine Entschuldigung dafür anderen ihre Zeit zu stehlen.
hustbaer schrieb:
Jedem kann mal ein Fehler passieren, man kann Dinge überlesen/übersehen, alles kein Problem. Daher hab' ich auch erst noch ganz sachlich/freundlich geantwortet.
Nur wenn das selbe unpassende Zeug dann wieder und wieder kommt, dann reichts halt irgendwann.Ich stehe weiterhin dazu, dass alles, was ich geschrieben habe, korrekt war. Wenn davon irgend etwas technisch falsch (oder unvollständig) gewesen sein sollte, lasse ich mich gerne korrigieren. Aber ob nun die Punkte, die ich erklärt habe, für das Problem wichtig bzw. relevant sind, darüber mag man subjektiv unterschiedlicher Meinung sein. Ich bin der Meinung, dass ja. Du ganz offensichtlich nicht. So oder so, ist es kein angemessenes Verhalten, meine Beiträge als "sinnlos" abzutun. Selbst wenn Du der Meinung bist, mein Beträge hätten das Thema nicht weiter gebracht (eine Meinung die ich keineswegs teilen kann), dann solltest Du anerkennen, dass hier jemand in guter Absicht versucht zu helfen. Indem Du immer gleich drauf haust, wenn jemand mal - deiner Meinung nach - nicht die "perfekte" Antwort liefert, sorgst Du höchstens dafür, dass dass hier bald keiner mehr Lust verspürt, sich an der Diskussion zu beteiligen. Bei mir hast Du das übrigens geschafft.
DeathCubeUK schrieb:
hustbaer schrieb:
da du im Gegensatz zu mir keine Erfahrung mit dem Thema zu haben scheinst
Mit dieser Behauptung liegst Du falsch.
Naja, macht halt nicht den Eindruck.
DeathCubeUK schrieb:
(...)Einige mögliche Ursachen, die der OP nun überprüfen kann/sollte, habe ich genannt. Das es evtl. doch ein anderes Problem sein könnte, dass noch nicht genannt wurde, habe ich nie ausgeschlossen...
1. Kann der OP ausschließen, dass an irgend einer Stelle evtl. doch "fremd" DLL's im Spiel sind, die (wie ich erläutert habe) sehr wohl Probleme verursachen können, auch dann wenn sie selbst weder Quelle noch Ziel der Exception sind? Ich behaupte an dieser Stelle nicht, dass das das Problem ist, sondern weise lediglich darauf hin, dass man es im Hinterkopf behalten und ggf. überprüfen sollte.
2. Ich habe darauf hin gewiesen, dass es generell besser ist, C++ Exceptions abzufangen, bevor sie die DLL verlassen und stattdessen geeignete Fehlercodes zurück zugeben. Ich spreche dabei aus langjähriger Erfahrung in der Entwicklung diverser kommerzieller Projekte, auf verschiedenen Plattform (Windows, Linux, MacOS) und verschiedenen Compilern (MSVC, GCC/MingW, etc). Du kannst hier natürlich gerne anderer Meinung sein, solltest meine Meining - die ich für durchaus begründet halte - aber trotzdem respektieren!
(Dies wird übrigens auf absehbare Zeit mein letzter Beitrag hier sein. Ich bin es einfach Leid, mich für ein oder zwei Beiträge anschließend endlos rechtfertigen zu müssen)
-
DeathCubeUK schrieb:
Falls ein inhaltlich korrekter und in guter Absicht verfasster Post nicht zur sofortigen Lösung des Problems führen sollte, dann ist eine angemessene Antwort: "Danke, dass Du Dir die Zeit genommen hast, diese richtigen und wichtigen Punkte zu erläutern. Leider war mir das meiste davon schon bekannt und ich kann ausschließen, dass mein Problem auf einen dieser Punkte zurückzuführen ist." Damit ist die Sache erledigt und es kann weiter gehen.
Lies vielleicht nochmal meine erste Antwort an dich in diesem Beitrag:
https://www.c-plusplus.net/forum/p2441806#2441806
Da war bitteschön nichts unfreundliches dran. Ich habe bestätigt dass einige deiner Aussagen korrekt sind bzw. (wörtlich) "zum Teil richtig" sind (inklusive sachlicher Erklärung warum ich es nur für "zum Teil richtig" halte).
Weiters die sachliche Klarstellung dass dein Beitrag auf das Problem des OP nicht anwendbar ist.Nach deiner Aussage könnte es jetzt also "weiter gehen". Tut es aber nicht, denn dann kommt...
https://www.c-plusplus.net/forum/p2441814#2441814
Eine weitere Belehrung über immer noch (auf die Fragestellung bezogen) total irrelevante Dinge.Und dann fängt es halt an lästig zu werden, weil sich ein gewisses Bild abzeichnet.
DeathCubeUK schrieb:
Dies wird übrigens auf absehbare Zeit mein letzter Beitrag hier sein.
OK. Wenn du meinst.
DeathCubeUK schrieb:
Ich bin es einfach Leid, mich für ein oder zwei Beiträge anschließend endlos rechtfertigen zu müssen
Die alternative Lösung dafür wäre: schreib Beiträge die besser zum Thema passen.
-
DeathCubeUK schrieb:
Ich bin es einfach Leid, mich für ein oder zwei Beiträge anschließend endlos rechtfertigen zu müssen
Musst du nicht. Tue es nicht.
-
hustbaer schrieb:
Versuch mal ein neues, frisches EXE Projekt anzulegen und ein neues, frisches DLL Projekt, und dann mal den minimal nötigen Code schreiben um das zu testen. Also eine Funktion exportieren die z.B. nen std::runtime_error wirft, und die im Hauptprogramm in einem
try-catch(std::exception const&)
aufrufen.Ich habe jetzt mal eine komplett neue Solution mit minimalen Projekt-Inhalten erstellt. Tatsächlich funktioniert hier, dass die Exception die DLL verlässt.
Das habe ich in meinem ursprünglichen Projekt anders:
Ich benutze dort die ATL (sind nur Termplates), d2d1.lib (Direct2D), dwrite (DirectWrite) und Windowscodecs.lib.
Sonst fällt mir nicht weiter ein, was ich ggü. dem Dummy-Projekt anders habe.
Kann es an den D2D Libs liegen?
-
Weil du die ATL erwähnst: ist hier evtl. COM im Spiel?
Falls ja könnte ich mir evtl. vorstellen dass COM da irgendwie dazwischenpfuscht - vielleicht ein automatisch erstellter Proxy oder sowas.Nur die Verwendung der ATL ist auf jeden Fall kein Problem. Ich habe hier auch ein Projekt wo in der .EXE die ATL verwendet wird, wo die .EXE etliche (nicht-COM) DLLs nachlädt, die Fehler mittels Exceptions kommunizieren. Funktioniert alles wie es sollte.
Was D2D angeht: damit hab ich keine Erfahrung. Würde mich aber wundern wenn das irgendwie relevant wäre.
Nochwas: du schreibst die Exception "geht verloren". Was passiert denn statt der erwarteten Ausfürhung des catch-Blocks?
Läuft die Funktion nach der "throw" Anweisung weiter? Oder geht's an der DLL-Boundary weiter als ob die Funktion normal beendet worden wäre? Oder ...?Ansonsten kann ich dir nur noch empfehlen: bau Stück für Stück die Dinge die in dem Projekt drinnen sind wo es nicht funktioniert aus, und teste nach jedem Schritt ob es immer noch Probleme macht. (Oder auch umgekehrt: bau Stück für Stück die anderen Dinge ein, ausgehend von dem Projekt wo es jetzt funktioniert.)
-
Liegen Aufrufe von Fensterprozeduren auf dem Stack?
COM Aufrufe?