Boost.preprocessor String-Vergleich
-
kannst du die exception denn mit try {} catch(...) {} fangen?
Evtentuell wird eine Exception vom Typ boost::error_already_set geworfen? Wenn ja, kannst du danach mit PyErr_Print (oder so ähnlich) den Fehler ausgeben.
-
Maxi schrieb:
kannst du die exception denn mit try {} catch(...) {} fangen?
Evtentuell wird eine Exception vom Typ boost::error_already_set geworfen? Wenn ja, kannst du danach mit PyErr_Print (oder so ähnlich) den Fehler ausgeben.Also ich hab schon versucht die Exceptions zu fangen, bis jetzt aber ohne Erfolg. Dazu hab ich den Update() Aufruf vom Subject aus mit try catch( ... ) eingeschlossen und auch im Listener selbst in die Update Methode try catch benutzt. Beides hat leider nicht geklappt. Wenn ich nur wüsste, wo die Exception fliegt.
Hier übrigens die Fehlerbehandlung mit PyErr_Print:if ( boost::python::handle_exception( boost::bind(exec_file_test, sFile) ) ) { if (PyErr_Occurred()) { wxLogError( wxT("Fehler aufgetreten:") ); PyErr_Print(); boost::python::object sys(boost::python::handle<>(PyImport_ImportModule("sys"))); boost::python::object err = sys.attr("stderr"); std::string err_text = boost::python::extract<std::string>(err.attr("getvalue")()); wxLogMessage(err_text.c_str()); } else { wxLogError("A C++ exception was thrown for which " "there was no exception translator registered."); } }Das dunktioniert soweit, sprich ich kann mir die Python Fehlermeldungen im Programm ausgeben lassen.
-
So, ich konnte den Ursprung der Exception nun genau bestimmen:
struct Listener : Observer, boost::python::wrapper<Observer> { [...] virtual void Update(Subject* s) { this->get_override("Update")(s); //<-- Hier wird die Exception geworfen } [...] };Das blöde ist nur, dass selbst wenn ich die Exceptionbehandlung hinzufüge, kann ich die Ausnahme nicht auffangen:
struct Listener : Observer, boost::python::wrapper<Observer> { [...] virtual void Update(Subject* s) { try { this->get_override("Update")(s); } catch( ... ) { wxMessageBox("Fehler"); } } [...] };Ich bin ehrlich gesagt überfragt, was ich an der Stelle falsch mache. SCheinbar ist der Aufruf von this->get_override("Update")(s); falsch, aber ich weiß nicht wie es denn richtig aussehen müsste.
-
versuch ma noch das hier, dann kannst du es noch weiter eingrenzen:
void Update(Subject* s) { if(override f = get_override("Update")) f(s); // oder auch eventuell f(boost::ref(s)); else Listener::Update(s); }
-
Maxi schrieb:
versuch ma noch das hier, dann kannst du es noch weiter eingrenzen:
void Update(Subject* s) { if(override f = get_override("Update")) f(s); // oder auch eventuell f(boost::ref(s)); else Listener::Update(s); }Also vielen Dank für den Tipp, aber sobald f(s) oder f(boost::ref(s)); aufgerufen werden fliegt die Exception. Aber immerhin funktioniert scheinbar die get_override() Funktion. Fangen kann ich sie aber wiedermal nicht.
Die Frage die ich mir gerade stelle ist, ob das denn dann überhaupt eine Exception ist.
Die Nachrichti die ich bekomme lautet zumindest wie folgt:Runtime Error!
Program: blabla.exe
This application has requested the runtime to terminate it in an unusual way. Please Contact the application's support team for more information.Ich mein, das ist doch eine Nachricht einer nicht gefangenen Exception oder?
-
Gate schrieb:
Ich mein, das ist doch eine Nachricht einer nicht gefangenen Exception oder?
Nicht zwingend. Führ das Programm mal im Debug-Modus aus, dann solltest du mehr Informationen darüber bekommen.
-
So endlich,
ich hab nun herausgefunden, warum die Exception fliegt.
Die Übergabe von Paramtern vom C++ Programm zu Python funktioniert nicht.
Eigentlich hatte die Python Updatemethode ja einmal den self und dann den Subject Paramter. Mittelsthis->get_override("Update")(s);wollte ich das Subject an die Methode übergeben. Irgendwie funktioniert das nicht. Wenn ich also im pythonskript der Updatemethode nur noch den self paramter definiere und dann vom Programm aus
this->get_override("Update")();aufrufe geht es ohne exception.
Hat nun vllt. jemand ne Idee wie ich es hinbekomme doch noch den Subject Parameter zu übergeben?
-
was passiert, wenn du das machst:
Subject* s = ...; // als parameter oder sonstwas. boost::python::object o(s) this->get_override("Update")(o);So kommst du weiter in den Fehler rein, wenn die Exception in der Zeile mit python::object fliegt
-
Maxi schrieb:
was passiert, wenn du das machst:
Subject* s = ...; // als parameter oder sonstwas. boost::python::object o(s) this->get_override("Update")(o);So kommst du weiter in den Fehler rein, wenn die Exception in der Zeile mit python::object fliegt
Ah, das ist interessant, die Exception oder was auch immer, ich nenns jetzt mal Runtime Error, fligt beim Aufruf von
boost::python::object o(s)Also tippe ich mal, dass die Konvertierung vom Subject zu einem Pythonbjekt fehlschlägt. Liege ich damit soweit richtig? und wichtiger, was kann ich tun damit es klappt?
-
Ja, scheint so, als ob Subject* nicht an python übergeben werden kann.
zeig doch mal deine deklaration von Subject und wie du das in boost.python registrierst.
Und probiere mal boost::python::object(boost::ref(s))
-
Maxi schrieb:
Und probiere mal boost::python::object(boost::ref(s))
Hey, vielen Dank. Das hat nun endlich geklappt. Allerdings bleibt nun meine Frage, aufgrund derer ich überhaupt den Thread wieder hochgeholt habe:
Gibt es eine Möglichkeit das Slicing zu verhindern?
Als Beispiel:class CSVExporter(LoW.Listener): def Update(self,Subject): l = ["Ja", "Nein"] Choice = LoW.Choice("Sollen die Fachdaten als CSV Datei exportiert werden?",l) if Choice == "Ja": DoIt() def DoIt(): [...]Sobald hier nun innerhalb der Update Methode DoIt() aufgerufen wird, gibt es den gleichen Runtime Error wie schon zuvor.
Das dürfte ja daran liegen, dass im Programm selbst nur Listener gespeichert werden können, die aber eben keine weitere Methoden wie eben z.B. DoIt definiert haben. Ein typisches Slicing Problem. Also hat damit vllt. jemand Erfahrungen und Ideen wie ich den Fehler umgehen kann?