У меня есть следующий код:
#include <pybind11/pybind11.h>
namespace py = pybind11;
class Foo
{
private:
int value;
public:
Foo(int val) : value(val) {};
int getValue() { return value; }
};
class Bar
{
private:
Foo& mFoo;
public:
Bar(Foo& foo) : mFoo(foo) {}
int getValue() { return mFoo.getValue(); }
};
PYBIND11_MODULE(pyinterface2, m)
{
py::class_<Foo>(m, "Foo")
.def(py::init<int>());
py::class_<Bar>(m, "Bar")
.def(py::init<Foo&>(), py::keep_alive<1, 2>())
.def("getValue", &Bar::getValue);
}
Я специально использую py::keep_alive<1, 2>()
в конструкторе, чтобы убедиться, что объект Foo
в python не очищен перед объектом Bar
является.Когда я вызываю это, используя:
import pyinterface2
foo = pyinterface2.Foo(1)
bar = pyinterface2.Bar(foo)
print(bar.getValue())
Программа аварийно завершает работу при создании объекта bar
.Когда я удаляю py::keep_alive
, он работает как положено.Однако я боюсь, что сборщик мусора может уничтожить объект foo
до того, как уничтожит объект bar
, что будет означать сбой моей программы при попытке доступа к объекту bar
.Как правильно это сделать?