Can boost :: python pass ownership of an object to a python callback function?

I am currently passing a C ++ pointer to a python callback function using a function boost::python::call. This works fine, but if I do not subsequently delete the pointer in the C ++ code, I will introduce a memory leak.

I would like to pass a pointer to a callback, and the python garbage collector will handle the lifetime of the object. Right now, if I want to save the object passed to the callback, I have to make a deep copy.

I saw here that this is possible with the return values ​​of a wrapped C ++ function using return_value_policy<manage_new_object>. Is it possible to do something similar with arguments boost::python::call?

+4
source share
1 answer

The method manage_new_objectworks as a metafunction class, which converts the argument into a converted result, to which the responsible should respond. With regular call policies, it is used under the hood. We just need to directly use this metaphor class:

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 it py::handle<>, since the shell returns PyObject*instead py::object. If you want to be more direct, you can skip some of the instances of the intermediate type and just use:

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

I came across the above by checking guesses. Does it seem to work at least?

+4
source

All Articles