[C++-sig] Subclassing C++ classes in Python

Holger Joukl Holger.Joukl at LBBW.de
Mon Mar 16 09:04:11 CET 2015


Hi Ernie,

>   When I tries to use class exposed as ’wrapper’ as substitute for C
> ++ original class i am getting a segfault error (see example below).
> Is there is something wrong with a way i create a wrapper-class or
> it is not intended to work as substitute for a base class?

I haven't tried your code sample but you'd normally just expose the
wrapper class *instead* of the original class, with the name of "A".

Python users don't need to know about the wrapper class intricacies.

If you expose a non-pure-virtual method you should also add the
default implementation, just as you cited from
http://www.boost.org/doc/libs/1_57_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
(necessary to avoid infinite recursion if your Python override
implementation calls the
C++ base class method)

I.e. something like (untested! Stick closely to the tutorial if in doubt)

#include <iostream>
#include <boost/python.hpp>

class A
{
public:
    virtual ~A() { std::cout << "A destructor for object: " << this <<
                   std::endl; }

    virtual void info() { std::cout << "C++ A info for object" << this
                                    << std::endl; }
};


struct A_Wrapper : A, boost::python::wrapper<A>
{
    void info(
    {
        if (override info_override = this->get_override("info")) {
            return info_override();
        }
        return A::info();
    }

    void default_info() { return this->A::info(); }
};


BOOST_PYTHON_MODULE(subclass)
{
    boost::python::class_<A_Wrapper, boost::noncopyable>("A",
        boost::python::init <>() )
       .def("info", &A::info, &A_Wrapper::default_info)
    ;
}

So the wrapper class provides you with the callback-ability to Python and
this is the one to expose.

As per the segfault you get: I guess that this might stem from your not
calling the boost::python::wrapper<A> base class constructor in your
A_Wapper
constructor (note how I didn't provide a constructor for the wrapper
class):

A_Wrapper() : A() {} // <-- not calling all base constructors here

Again, haven't actually tried it.

Holger

Landesbank Baden-Wuerttemberg
Anstalt des oeffentlichen Rechts
Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz
HRA 12704
Amtsgericht Stuttgart


More information about the Cplusplus-sig mailing list