2016-06-01 11 views
4

Ich übergebe derzeit einen C++ - Zeiger auf eine Python-Callback-Funktion mit der boost::python::call-Funktion. Das funktioniert gut, aber wenn ich den Zeiger im C++ - Code später nicht lösche, führe ich ein Speicherleck ein.Kann boost :: python den Besitz eines Objekts an eine Python-Callback-Funktion übergeben?

Ich würde gerne den Zeiger auf den Rückruf übergeben und Python Garbage Collector behandeln die Lebensdauer des Objekts. Wenn ich jetzt das an den Callback übergebene Objekt speichern möchte, muss ich eine tiefe Kopie machen.

Ich habe here gesehen, dass diese Art von Sache mit Rückgabewerten der umschlossenen C++ Funktion mit return_value_policy<manage_new_object> möglich ist. Ist es möglich, etwas ähnliches mit den Argumenten zu boost::python::call zu tun?

Antwort

4

Die Methode manage_new_object funktioniert, indem sie eine Metafunktionsklasse ist, die ein Argument in ein konvertiertes Ergebnis umwandelt, für das der Aufrufer die Verantwortung übernehmen muss. Mit den normalen Anrufrichtlinien wird es unter der Haube verwendet. Wir müssen nur uns selbst, dass metafunction Klasse verwenden, ausdrücklich:

struct Foo { 
    X* x = ...; 

    void give_up_x(py::object callback) { 
     py::manage_new_object::apply<X*>::type wrapper; 
     callback(py::handle<>{wrapper(x)}); 
    } 
}; 

Sie benötigen py::handle<> seit Wrapper ein PyObject* anstelle eines py::object gibt Ihnen zurück. Wenn Sie mehr direkt sein möchten, können Sie einige der Zwischen-Typ instantiations überspringen und benutzen Sie einfach:

void give_up_x(py::object callback) { 
    callback(py::handle<>{py::detail::make_owning_holder::execute(x)}); 
} 

ich auf die oben durch Vermutung-and-Check kam. Es sieht so aus, als ob es zumindest funktioniert?