boost::python abstract base class
I am trying to get raw pointers and abstract base classes working properly with boost::python v2. I am working on an example inspired by the tutorial http://www.boost.org/libs/python/doc/tutorial/doc/inheritance.html. In my case, the base class has a pure virtual function, but I don't need to override it in python and call it from c++, so I don't think I need to do a BaseWrap. The problem is that if I try and expose Base to python, I get the compiler (gcc 3.2) error: g++ -isystem/usr/local/include -I/usr/local/include/python2.2 -fPIC -ftemplate-depth-100 -c rawpointer.cpp /usr/local/include/boost/python/object/value_holder.hpp: In instantiation of `boost::python::objects::value_holder<Base>': /usr/local/include/boost/type_traits/alignment_of.hpp:52: instantiated from `boost::detail::alignment_of_impl<boost::python::objects::value_holder<Base> >' /usr/local/include/boost/python/object/instance.hpp:29: instantiated from `boost::alignment_of<boost::python::objects::value_holder<Base> >' ...snip... rawpointer.cpp:47: instantiated from here /usr/local/include/boost/python/object/value_holder.hpp:36: cannot declare field `boost::python::objects::value_holder<Base>::m_held' to be of type ` Base' /usr/local/include/boost/python/object/value_holder.hpp:36: because the following virtual functions are abstract: rawpointer.cpp:15: virtual const std::string& Base::get_name() rawpointer.cpp:14: virtual void Base::sayit() const make: *** [rawpointer.o] Error 1 and if I only expose the derived classes, the code compiles but then I get a runtime error when I try and import the class in python
import rawpointer Traceback (most recent call last): File "<stdin>", line 1, in ? RuntimeError: extension class wrapper for base class 4Base has not been created yet
Below is my example code. Suggestions welcomed! John Hunter // work with raw pointers #include <iostream> #include <string> #include <boost/python.hpp> #include <boost/python/manage_new_object.hpp> using namespace boost::python; class Base { public: virtual ~Base() {}; virtual void sayit() const=0; virtual const std::string& get_name()=0; private: }; class Foo : public Base { public: Foo() : _name("Foo") {} void sayit() const { std::cout << "Foo" << std::endl; } const std::string& get_name() {return _name;} private: const std::string _name; }; class Bar : public Base { public: Bar() : _name("Bar") {} void sayit() const { std::cout << "Bar" << std::endl; } const std::string& get_name() {return _name;} private: const std::string _name; }; Base* barfactory(){ return new Bar(); } Base* foofactory(){ return new Foo(); } std::string simonsays(Base* p) {return p->get_name();} BOOST_PYTHON_MODULE_INIT(rawpointer) { class_<Base>("Base", no_init) .def("sayit", &Base::sayit); class_<Foo, bases<Base> >("Foo") .def("sayit", &Foo::sayit); class_<Bar, bases<Base> >("Bar") .def("sayit", &Bar::sayit); def("foofactory", foofactory, return_value_policy<manage_new_object>()); def("barfactory", barfactory, return_value_policy<manage_new_object>()); def("simonsays", simonsays); }
Hi John, Usually the best place for Boost.Python questions is: http://www.python.org/sigs/c++-sig/ John Hunter <jdhunter@ace.bsd.uchicago.edu> writes:
I am trying to get raw pointers and abstract base classes working properly with boost::python v2. I am working on an example inspired by the tutorial http://www.boost.org/libs/python/doc/tutorial/doc/inheritance.html.
BTW, more up-to-date docs are here: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/p...
In my case, the base class has a pure virtual function, but I don't need to override it in python and call it from c++, so I don't think I need to do a BaseWrap.
The problem is that if I try and expose Base to python, I get the compiler (gcc 3.2) error:
g++ -isystem/usr/local/include -I/usr/local/include/python2.2 -fPIC -ftemplate-depth-100 -c rawpointer.cpp /usr/local/include/boost/python/object/value_holder.hpp: In instantiation of `boost::python::objects::value_holder<Base>': /usr/local/include/boost/type_traits/alignment_of.hpp:52: instantiated from `boost::detail::alignment_of_impl<boost::python::objects::value_holder<Base> >' /usr/local/include/boost/python/object/instance.hpp:29: instantiated from `boost::alignment_of<boost::python::objects::value_holder<Base> >' ...snip... rawpointer.cpp:47: instantiated from here /usr/local/include/boost/python/object/value_holder.hpp:36: cannot declare field `boost::python::objects::value_holder<Base>::m_held' to be of type ` Base' /usr/local/include/boost/python/object/value_holder.hpp:36: because the following virtual functions are abstract: rawpointer.cpp:15: virtual const std::string& Base::get_name() rawpointer.cpp:14: virtual void Base::sayit() const make: *** [rawpointer.o] Error 1
Yeah, it's trying to instantiate the copy constructor for your base type.
BOOST_PYTHON_MODULE_INIT(rawpointer) { class_<Base>("Base", no_init) .def("sayit", &Base::sayit);
Try class_<Base, noncopyable>("Base", no_init) .def("sayit", &Base::sayit); instead.
class_<Foo, bases<Base> >("Foo") .def("sayit", &Foo::sayit); class_<Bar, bases<Base> >("Bar") .def("sayit", &Bar::sayit);
def("foofactory", foofactory, return_value_policy<manage_new_object>()); def("barfactory", barfactory, return_value_policy<manage_new_object>());
def("simonsays", simonsays); }
-- David Abrahams dave@boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution
"David" == David Abrahams <dave@boost-consulting.com> writes:
David> Usually the best place for Boost.Python questions is: David> http://www.python.org/sigs/c++-sig/ Just subscribed -- I'll go there next time. David> BTW, more up-to-date docs are here: Noted. David> class_<Base, noncopyable>("Base", no_init) That did it; many thanks. John Hunter
participants (2)
-
David Abrahams
-
John Hunter