inheritance - Boost Python Runtime error when passing object of derived type from python to C++ function expecting a shared_ptr to base type -
i have function takes std::shared_ptr, , want pass object of derived type function python. here's class definitions:
struct abstractbase { virtual void foo() = 0; }; struct derived : public abstractbase { virtual void foo(){ std::cout<<"derived's foo!"<<std::endl; } }; struct unrelated { void bar(std::shared_ptr<abstractbase> base_shared_ptr) { base_shared_ptr->foo(); } }; #endif /* classes_h */ a simple pure c++ example want:
int main() { std::shared_ptr<derived> d(new derived); unrelated u; u.bar(d); } output: derived's foo!
here boost.python wrapper code:
#include <boost/python.hpp> #include "classes.h" boost_python_module(shared_ptr_test) { using namespace boost::python; class_<abstractbase,std::shared_ptr<abstractbase>,boost::noncopyable>("abstractbase",no_init); class_<derived,std::shared_ptr<derived>,bases<abstractbase>,boost::noncopyable>("derived"); class_<unrelated,std::shared_ptr<unrelated>,boost::noncopyable>("unrelated") .def("bar",&unrelated::bar); } and here's simple python test:
import shared_ptr_test d=shared_ptr_test.derived() u=shared_ptr_test.unrelated() u.bar(d) to dismay, not work. compiles fine, when run python script, error:
traceback (most recent call last): file "test.py", line 5, in <module> u.bar(d) boost.python.argumenterror: python argument types in unrelated.bar(unrelated, derived) did not match c++ signature: bar(unrelated {lvalue}, std::shared_ptr<abstractbase>) changing bar take shared_ptr<derived> fixes this, know internally boost.python managing objects shared_ptrs. there more need boost.python realize okay pass shared_ptr<derived> function expecting shared_ptr<base>?
boost.python needs aware smart pointer derived can converted smart pointer abstractbase. can accomplished either of following:
- using
boost::shared_ptr. boost.python has code handle implicit conversions betweenboost::shared_ptrs whenelement_typehierarchical. register implicit conversion
std::shared_ptr<derived>std::shared_ptr<abstractbase>viaboost::python::implicitly_convertible.std::shared_ptrmeets concept requirementsimplicitly_convertible, requires registering conversion in module definition:implicitly_convertible<std::shared_ptr<derived>, // source std::shared_ptr<abstractbase> >(); // target