ブースト 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++ の削除が呼び出されることが予想されます。それは決して起こらないので、オブジェクトをリークします。
これを行うためにさまざまな手法を試しましたが、すべてを機能させることはできませんでした。おそらく上記の例を変更する方法を示す完全な例をいただければ幸いです。