Передача объектов C ++ в python с boost

Я пытаюсь понять, как использовать 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 из a_list, я ожидаю, что удаление c ++ будет вызвано для объекта, который я создал с помощью new. Этого никогда не происходит, и поэтому я пропускаю предметы.

Я перепробовал много вариантов техники, но так и не смог заставить все работать. Я был бы очень признателен за полный пример, возможно, показывающий, как изменить приведенный выше пример.

4

Решение

Я уверен, что ptr() не имеет никакого отношения к времени жизни объекта, на который указывает Вы полностью управляете жизнью, если используете ее. (Я считаю, что использовать его — все равно что использовать PyCObject.)

То, что вы можете сделать, это определить тип указателя A как shared_ptr (boost или std, не имеет значения). Что-то вроде этого:

class_<A, shared_ptr<A>, boost:noncopyable>("A", init<>());

Тогда вы можете сделать так, чтобы ваша фабричная функция сделала это:

void passNewAToPython()
{
A * a = make_shared<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", a);
PyGILState_Release(_GILState);
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector