我试图弄清楚如何使用 boost python 在 c++ 中创建一个对象并将其传递给 Python。我设法做到了这一点,但随后无法进行垃圾收集。
想象一下 A 类是在 C++ 中的某个地方定义的。passNewAToPython() 函数是从代码中的其他地方调用的,它创建一个 A 对象,然后将它传递给 Python 中的回调函数。我希望将特定实例传递给 python 而不是副本,因此使用 ptr()
static PyObject * pythonCallbacks;
void passNewAToPython()
{
A * a = new A();
PyGILState_STATE _GILState = PyGILState_Ensure();
//Should really use a try catch here too but lets ignore that for now
boost::python::call_method<void>(pythonCallbacks, "newA", boost::python::ptr(a));
PyGILState_Release(_GILState);
}
void initmodule(PyObject* userCallCallbacks_)
{
PyEval_InitThreads();
pythonCallbacks = userCallCallbacks_;
}
BOOST_PYTHON_MODULE(mymodule)
{
def("initmodule", initmodule);
class_<A, boost::noncopyable>("A", init<>());
}
Python 代码
import mymodule
class pythonCallbacks(object):
a_list = [];
def newA(self, a):
self.a_list.append(a)
callbacks = pythonCallbacks()
mymodule.initmodule(callbacks)
现在想象一下在调用 newA 回调之后的一段时间。我希望存储实例的唯一位置是在 a_list 中。因此,如果我从 a_list 中删除 a ,那么我希望在我使用 new 创建的对象上调用 c++ 删除。那永远不会发生,所以我泄漏了对象。
我尝试了许多技术变体来做到这一点,但从未设法使一切正常。我真的很感激一个完整的例子,也许展示了如何修改上面的例子。