Closed
Description
Hi,
I have an issue with the ref counting of python objects that are passed to C++.
I have a C++ class Vector
that the use can inherit from (hence I also have a PyVector
trampoline class). The user-defined python class should then be passed back to C++ where some actions on this class are performed. Unfortunately, it seems that python takes complete ownership of the class, so that it gets deleted even if the C++ side still needs it.
MFE:
#include <pybind11/pybind11.h>
#include <iostream>
#include <memory>
namespace py = pybind11;
class Vector : public std::enable_shared_from_this<Vector> {
public:
Vector() {}
virtual void print() {
std::cout << "Vector" << std::endl;
}
};
class PyVector : public Vector {
public:
virtual void print() override {
PYBIND11_OVERLOAD(void, Vector, print,);
}
};
class Foo {
public:
Foo(std::shared_ptr<Vector> vec) : _vec(vec){}
std::shared_ptr<Vector> _vec;
void print() {
_vec -> print();
}
};
PYBIND11_MODULE(cmake_example, m) {
py::class_<Vector, std::shared_ptr<Vector>,
PyVector>(m, "Vector")
.def(py::init<>());
py::class_<Foo, std::shared_ptr<Foo>>(m, "Foo")
.def(py::init<std::shared_ptr<Vector>>())
.def("print", &Foo::print);
}
Python code:
import cmake_example as m
class MyVector(m.Vector):
def print(self):
print("MyVector")
def __del__(self):
print("I was deleted")
def make_foo():
x = MyVector()
foo = m.Foo(x)
foo.print()
return foo
myfoo = make_foo()
myfoo.print()
Output:
MyVector
I was deleted
Vector
Expected output:
MyVector
MyVector
I was deleted