Reputation: 2823
I am currently passing a C++ pointer to a python callback function with the boost::python::call
function. This works fine, but if I don't subsequently delete the pointer in the C++ code, I introduce a memory leak.
I would like to pass the pointer to the callback and have python's garbage collector handle the lifetime of the object. Right now, if I want to save the object passed to the callback, I have to do a deep copy.
I have seen here that this sort of thing is possible with return values of wrapped C++ function with return_value_policy<manage_new_object>
. Is it possible to do something similar with the arguments to boost::python::call
?
Upvotes: 4
Views: 584
Reputation: 302643
The way manage_new_object
works is by being a metafunction class that converts an argument into a converted result that the caller must take responsibility for. With the normal call policies, it's used under the hood. We just have to use that metafunction class explicitly ourselves:
struct Foo {
X* x = ...;
void give_up_x(py::object callback) {
py::manage_new_object::apply<X*>::type wrapper;
callback(py::handle<>{wrapper(x)});
}
};
You need py::handle<>
since wrapper gives you back a PyObject*
instead of a py::object
. If you want to be more direct, you can skip some of the intermediate type instantiations and just use:
void give_up_x(py::object callback) {
callback(py::handle<>{py::detail::make_owning_holder::execute(x)});
}
I came upon the above through guess-and-check. It looks like it works at least?
Upvotes: 4