[C++-sig] [Boost Python] Extended class loosing attributes when saving as pointer to BaseClass in C++

Jim Bosch talljimbo at gmail.com
Fri Jan 22 21:05:32 CET 2010


I think I can explain what's going on, and I've got an idea for a
partial solution.

But first, try making BaseClassWrap multiply inherit from BaseClass and
boost::python::wrapper<BaseClass>.  That might fix everything.  If not,
read on...

When boost::python converts a C++ value to Python, it looks up the C++
RTTI type name in a registry and finds a converter for that type.  Those
converters generally make a new Python object, and put a
boost::python::instance_holder in it, containing a C++ object by value
or [smart] pointer.  But what you want is to extract the PyObject* from
the C++ object and just incref and return that.  I think you could do
this by writing your own Python version of BaseClassManager that checks
for this possibility:


object PyBaseClassManager_getObjectByName(
    BaseClassManager & manager,
    std::string const & name
) {
    shared_ptr<BaseClass> r = manager.getObjectByName(name);
    shared_ptr<BaseClassWrap> w =
        dynamic_pointer_cast<BaseClassWrap>(r);
    if (w) {
        handle<> h(w->self);
        return object(h);
    }
    return object(r);
}

...unfortunately, you'd have to do that with ANY C++ function that
returns a shared_ptr<BaseClass>.  A better solution would be to write a
custom to-python conversion for shared_ptr<BaseClass>, or if necessary a
custom ResultConverterGenerator to do that work, but that's a little
more complicated.

This is probably something boost::python should do automatically if
BaseClassWrap is a subclass of wrapper<BaseClass>.  If it doesn't, and
you can get me a complete example that demonstrates the problem, I'll
see about making a patch to make that happen.

Jim Bosch



More information about the Cplusplus-sig mailing list