boost::python 可以将对象的所有权传递给 python 回调函数吗?

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

我目前正在使用 boost::python::call 函数将 C++ 指针传递给 python 回调函数。这工作正常,但如果我随后不删除 C++ 代码中的指针,就会引入内存泄漏。

我想将指针传递给回调并让 python 的垃圾收集器处理对象的生命周期。现在,如果我想保存传递给回调的对象,我必须进行深拷贝。

我已经看到 here 使用 return_value_policy<manage_new_object> 包装的 C++ 函数的 return 值可以实现这种事情。是否可以对 boost::python::call?

的参数做类似的事情

manage_new_object 的工作方式是作为元函数 class 将参数转换为调用者必须负责的转换结果。对于正常的呼叫策略,它是在幕后使用的。我们只需要自己显式地使用元函数 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)});
    }
};

您需要 py::handle<>,因为 wrapper 返回 PyObject* 而不是 py::object。如果想更直接一些,可以跳过一些中间类型实例化,直接使用:

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

我是通过猜测和检查得出上述结论的。看起来它至少有效?