You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm wrapping an interface (abstract base class) with pybind. This interface is not meant to be instantiated in python, it's only purpose is showing the inheritance (and if possible wrapping the functions such that they get forwarded to the children). All calls on this Interface take Interface*/Interface&/shared_ptr(doesn't matter, crashes for all). Classes that implement this interface usepublich virtual Interfaceto inherit the Interface. When calling a wrapped function that takes anInterface*with a python instance of a derived object, the C++ pointer loses it's vtable and calling a method on this pointer causes a segmentation fault. Removing thevirtual` part of the inheritance solves the problem (but that is not an option in my case).
The code compiles and runs fine with gcc but fails with Visual Studio 2017 Win64
Reproducible example code
#include <memory>
#include <pybind11/pybind11.h>
namespace py = pybind11;
class Base {
public:
virtual ~Base() = default;
virtual int foo() = 0;
// virtual int bar(std::shared_ptr<Base> ptr) = 0;
virtual int bar(Base& ptr) = 0;
virtual int bar(Base* ptr) = 0;
};
# Remove the 'virtual' in the next line and it will won't crash anymore
class Derived : public virtual Base {
public:
virtual ~Derived() = default;
// int bar(std::shared_ptr<Base> ptr) override { return ptr->foo() + 88; }
int bar(Base* ptr) override { return ptr->foo() + 88; }
int bar(Base& ptr) override { return ptr.foo() + 88; }
int foo() override { return 44; }
};
PYBIND11_MODULE(test_foo, m) {
py::class_<Base
//,std::shared_ptr<Base>
>(m,
"Base"); // .def("bar", &Base::bar);
py::class_<Derived, Base
//, std::shared_ptr<Derived>
>(m, "Derived")
.def(py::init<>());
//.def("bar", &Derived::bar);
// m.def("get_sptr", [](std::shared_ptr<Base> b) { return b->bar(b); });
m.def("get_ref", [](Base& b) { return b.bar(b); });
m.def("get_ptr", [](Base* b) { return b->bar(b); });
// m.def("run_cpp", []() {
// auto b = std::make_shared<Derived>();
// return b->bar(b);
//});
}
Python code
import test_foo
# This version works for shared pointers
#print(test_foo.run_cpp())
d = test_foo.Derived()
print(test_foo.get_ptr(d))
print(test_foo.get_ref(d))
#print(test_foo.get_sptr(d))
The text was updated successfully, but these errors were encountered:
We currently automatically detect multiple inheritance (when registered
with pybind) to enable non-simple casting, but simple casting is also
invalid when there is single-base, virtual inheritance (pybind#1256). (This
happens to work under gcc/clang, but makes MSVC segfault when upcasting).
This commit adds detection for a specified base class being a virtual
base, and if so, turns on the `multiple_inheritance` flag to mark the
class and base as non-simple, and adds tests (which segfault under MSVC
without this fix).
(Earlier versions can work around the issue by explicitly passing a
`py::multiple_inheritance{}` option to the `py::class_<...>` constructor).
Co-authored-by: Jason Rhinelander <[email protected]>
Issue description
I'm wrapping an interface (abstract base class) with pybind. This interface is not meant to be instantiated in python, it's only purpose is showing the inheritance (and if possible wrapping the functions such that they get forwarded to the children). All calls on this Interface take
Interface*
/Interface&
/shared_ptr(doesn't matter, crashes for all). Classes that implement this interface use
publich virtual Interfaceto inherit the Interface. When calling a wrapped function that takes an
Interface*with a python instance of a derived object, the C++ pointer loses it's vtable and calling a method on this pointer causes a segmentation fault. Removing the
virtual` part of the inheritance solves the problem (but that is not an option in my case).The code compiles and runs fine with
gcc
but fails withVisual Studio 2017 Win64
Reproducible example code
Python code
The text was updated successfully, but these errors were encountered: