Boost.Python : Im C++ Code auf self zugreifen
-
Hi,
ich portiere gerade eine C++ Bibliothek nach Python und würde gerne soetwas machen können:class Step { void step(); };
Python:
def OnStep(self): print("Blabla") step = Step() step.OnStep = OnStep step.step(); // Ruft OnStep auf, falls gesetzt.
Dazu müsste ich ja innerhalb von Step::step auf das entsprechende Objekt zugreifen können. boost::python::object(this) erzeugt leider eine neue Instanz.
Wie würde sich das am besten so lösen lassen?Grüße,
Ethon
-
http://www.boost.org/doc/libs/1_48_0/doc/html/signals.html
Signals/Slots/Callbacks
sind die Stichworte die du suchst.
-
Du meinst dass ich einen Callback fest als Attribut im Python Objekt einbaue?
Wäre möglich, aber schöner wäre es halt Pythons dynamisches System zu nutzen, wenn man schon zur Laufzeit Methoden hinzufügen kann.
Wenn es halt geht ohne hässlich zu werden.Habe eine alte Beschreibung gefunden, wie man per Boost.Python virtuelle Funktionen aufruft (die in Python implementiert werden können):
http://wiki.python.org/moin/boost.python/OverridableVirtualFunctions#Pure_Virtual_FunctionsSo soll man sich auch das Self-Objekt abgreifen können, das Problem ist dass dazu Dokumentation praktisch nicht existent ist und ich gerade nicht durchblicke.
Edit: Also, um das zu klären: Meine Idee war dass das Objekt kein Attribut OnStep hat. Das kann man aber ja in Python zur Laufzeit noch hinzufügen. step() prüft einfach ob das Attribut existiert, falls ja wird es aufgerufen, ansonsten eben nicht.
-
Ethon schrieb:
Edit: Also, um das zu klären: Meine Idee war dass das Objekt kein Attribut OnStep hat. Das kann man aber ja in Python zur Laufzeit noch hinzufügen. step() prüft einfach ob das Attribut existiert, falls ja wird es aufgerufen, ansonsten eben nicht.
Ja das geht in C++ nicht so 1:1 weil du das Objekt OnStep brauchst.
Aber OnStep kann zB ein slot sein. Und per Template Method Pattern (wenn du vererbung brauchst) kann step() dann den slot callen (und der tut halt nix solange er nicht connected ist).Dann hättest du etwa:
typedef void (*func)(); class Step { private: signal<func> onStep; public: void step() { onStep(); } void setOnStep(func newOnStep) { onStep.connect(newOnStep); } }; .... Step s; s.setOnStep(foo); s.step(); //called uA foo()
Aber um ehrlich zu sein - ich bin gerade etwas verwirrt. Willst du Python Code nach C++ portieren oder willst du Python Code aus C++ heraus ansprechen? Wenn zweiteres, dann vergiss was ich gesagt habe.
-
Aber um ehrlich zu sein - ich bin gerade etwas verwirrt. Willst du Python Code nach C++ portieren oder willst du Python Code aus C++ heraus ansprechen? Wenn zweiteres, dann vergiss was ich gesagt habe.
Ein ziemliches Zwischending.
Ich möchte eine Bibliothek für Python schreiben, die von mehreren C++-Bibliotheken abhängt. Die Bibliotheken ganz/teilweise nach Python zu exportieren wäre beträchtlich mehr Arbeitsaufwand als die Python-Bibliothek Python-freundlich in C++ zu implementieren.OnStep wird in jedem Fall im Python-Code implementiert. Mit Boost-Python ist das auch sehr einfach zum Aufrufen (Der operator() von boost::python::object ist überladen).
Wenn ich jetzt eine Funktion zum Setzen des Callbacks schreiben würde, dann würde ich ja in C++ etwas machen, was Python genauso gut/besser und mit schönerer Syntax alleine könnte.
Ich würde gerne soetwas machen:
void step() { boost::python::object self = /* */; if(has_attr(self, "OnStep")) self.attr("OnStep")(); }