In pybind11 2.0.1, calling a function of a derived class works as expected, e.g.,
struct Base {};
struct Deriv: Base {};
void show(std::shared_ptr<Base> & b) {return;}
PYBIND11_PLUGIN(foo) {
py::module m("foo");
py::class_<Base>(m, "Base")
.def(py::init<>());
py::class_<Deriv, Base>(m, "Deriv")
.def(py::init<>());
m.def("show", &show);
}
import foo
d = foo.Deriv()
foo.show(d)
md5-23c5922ec9e6b4e77fe9228b623c5da5
RuntimeError: Unable to load a custom holder type from a default-holder instance
The error is happening because the default holder for pybind classes is std::unique_ptr, which can't be converted to a shared_ptr. 2.1 added detection and failure for this; I'm not entirely sure what would have happened in 2.0 (perhaps a double free?).
The easiest fix is to change the holder on the registered types to shared_ptr with:
py::class_<Base, std::shared_ptr<Base>>(...);
py::class_<Derived, Base, std::shared_ptr<Derived>>(...);
(On a separate note, you'll want to make sure Base has a virtual destructor for anything more than a trivial class.)
Thanks, this fixes it.
It worked! hurrey..
Most helpful comment
The error is happening because the default holder for pybind classes is
std::unique_ptr, which can't be converted to ashared_ptr. 2.1 added detection and failure for this; I'm not entirely sure what would have happened in 2.0 (perhaps a double free?).The easiest fix is to change the holder on the registered types to
shared_ptrwith:(On a separate note, you'll want to make sure
Basehas a virtual destructor for anything more than a trivial class.)