Exception in dynamischer Bibliothek werfen
-
Ich möchte eine Exception in einer Funktion werfen, die in einer dynamischen Bibliothek definiert ist. Die Exception jedoch ist im Hauptprogramm definiert, das das Exception-Objekt dann auch fangen soll. Allerdings fängt er es anscheinend nur, wenn ich direkt im Hauptprogramm werfe; wenn ich es in der Bibliothek tue, fällt die Exception bis ganz nach oben durch. Warum macht das einen Unterschied, kann das das nicht machen?
Exception.h:
#include <string> // Simple Exception-Klasse class Exception { std::string msg; public: Exception(std::string); std::string getMessage(); };Exception.cpp:
#include <string> using std::string; #include "Exception.h" Exception::Exception(string m) : msg(m) {} string Exception::getMessage() { return msg; }library.cpp:
#include <string> using std::string; #include "Exception.h" // Was ich bekomme: Callback-Constructor-Typ typedef Exception* (*ctor_t)(string); extern "C" { void init(ctor_t ctor) { throw ctor("foo"); // wirf eine neue Exception } }program.cpp:
#include <iostream> #include <string> #include <dlfcn.h> using std::cout; using std::endl; using std::string; #include "Exception.h" // Ich muss das Objekt ja im Hauptprogramm erstellen... Exception* ctor(string msg) { return new Exception(msg); } // Was ich gebe: Callback-Constructor-Typ typedef Exception* (*ctor_t)(string); // Was ich aus der Bibliothek lade typedef void (*init_t)(ctor_t); int main() { // OK, Bibliothek laden, das klappt ja alles void* lib = dlopen("./library.so", RTLD_LAZY); init_t init = (init_t)dlsym(lib, "init"); // Jetzt wird's witzig, die Funktion aus der Bibliothek aufrufen: try { init(ctor); } catch(Exception* e) { // Aber dummerweise komme ich nie hier an cout << "Exception: " << e->getMessage() << endl; } return 0; }Funktionert aber nicht:
$ g++ -fPIC -c library.cpp $ g++ -shared -Wl,-soname,library.so -olibrary.so library.o $ g++ Exception.cpp program.cpp -ldl $ ./a.out terminate called after throwing an instance of 'Exception*' zsh: abort ./a.outPS: Das Problem scheint tatsächlich zu sein, dass er das, was da fliegt, nicht als Exception* erkennt. Wenn ich das Ding vor dem Werfen nach int caste und nach dem Fangen wieder zurück, funktionert es einwandfrei...
-
Hallo,
der C++ Standard schreibt nicht vor, ob das Werfen/Fangen von Exceptions über Bibliotheksgrenzen hinasus funktioniert, sowas ist im höchsten maße Compiler-abhängig. Im Allgemeinen funktioniert das nicht, da sich der Exception-Mechanismus von Compiler zu Compiler und von Runtime-Lib zu Runtime-Lib unterscheidet. Falls du wirklich diesen Weg beschreiten willst, wirst du ein passende Antwort auf deine Frage sich in der gcc-Doku finden.Gängige Praxis ist es aber, Exceptions nur lokal zu verwenden, sie also an Modulgrenzen zu fangen. Dort können sie z.B. dann auf Fehlercodes abgebildet werden.
-
Hilft das: http://www.gatago.com/gnu/gcc/15176800.html