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_ptr
s. 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_ptr
s whenelement_type
hierarchical. register implicit conversion
std::shared_ptr<derived>
std::shared_ptr<abstractbase>
viaboost::python::implicitly_convertible
.std::shared_ptr
meets concept requirementsimplicitly_convertible
, requires registering conversion in module definition:implicitly_convertible<std::shared_ptr<derived>, // source std::shared_ptr<abstractbase> >(); // target