I'm trying to figure out how to use boost python to create an object in c++ and pass it into Python. I've managed to do this but then can't get garbage collection to occur.
Imagine the class A is defined somewhere in C++. The passNewAToPython() function is called from somewhere else in the code which creates an A object and then passes it to a callback function in Python. I want that specific instance passing to python and not a copy hence the use of 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<>());
}
The Python code
import mymodule
class pythonCallbacks(object):
a_list = [];
def newA(self, a):
self.a_list.append(a)
callbacks = pythonCallbacks()
mymodule.initmodule(callbacks)
Now imagine some time later after the newA callback is called. The only place I expect the a instance to be stored is in a_list. So if I delete a from a_list then I would expect the c++ delete to be called on the object I created with new. That never happens and so I leak objects.
I've tried many variants of technique to do this but never managed to make everything work. I would really appreciate a complete example perhaps showing how to modify the above example.