Boost logo

Boost Users :

From: John Hunter (jdhunter_at_[hidden])
Date: 2002-12-20 10:40:47


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);
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net