EDIT(eric): Adding a tracking list.
py::wraper<>
trampoline shim with GC garbage collection (to prevent inheritance slicing) #2757 Using py::wrapper<>
and GC ressurrectionHello,
Consider deriving a C++ class in Python and overloading virtual functions, including a 'Clone' function.
When passing a derived Python object to C++ without holding a reference (like calling Clone()), the information about the Python type is lost. In this case the wrong base-class function is called. More complex cases may result in a SEGFAULT.
Is there any way to work around/fix this without causing memory leaks?
Thanks!
Reproducible example code test.cpp// test.cpp #include <pybind11/pybind11.h> #include <Python.h> #include <iostream> #include <memory> using std::cout; using std::endl; using std::unique_ptr; using std::shared_ptr; using std::make_shared; namespace py = pybind11; class Base { public: virtual void Print() { cout << "Base!" << endl; } virtual shared_ptr<Base> Clone() { return make_shared<Base>(); } }; class PyBase : public Base { public: using Base::Base; // Inherit constructors void Print() override { PYBIND11_OVERLOAD(void, Base, Print, ); } shared_ptr<Base> Clone() override { PYBIND11_OVERLOAD(shared_ptr<Base>, Base, Clone, ); } }; PYBIND11_MODULE(libtest, m) { py::class_<Base, py::wrapper<PyBase>, shared_ptr<Base>>(m, "Base") .def(py::init<>()) ; m.def("Test", [] ( shared_ptr<Base> b ) { shared_ptr<Base> d = b->Clone(); // Python object of d is already dead! d->Print(); // prints "Base!" }); }test.py
from libtest import * class Derived(Base): def __init__(self): super().__init__() def Print(self): print("Derived!") def Clone(self): return Derived() Test(Derived())
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4