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

MrF the.groovy.gregory at googlemail.com
Fri Jan 22 19:33:09 CET 2010


Hey,

My problem is the following:

I do have a C++ class, "BaseClass", that I am extending in Python 
("SubClass"). Also there is another C++ class, let's call it 
"BaseClassManager" which has a vector of BaseClass* (well, actually it's 
holding shared_ptr's). Instances of "SubClass" are created in Python, 
but ownership has been transferred to C++, as "BaseClassManager" holds 
all the objects.

Here is the code that illustrates this:

Wrapped BaseClassManager
------------------------------------
class_<BaseClassManager>("GameBaseX")
             .def("addObject", &BaseClassManager::addObject) // takes 
shared_ptr< BaseClass>&
             .def("getObjectByName", 
&BaseClassManager::getObjectByName); // takes a string, returns 
shared_ptr<BaseClass>


WrapperClass for Base (needed for transferring ownership)
------------------------------------
class BaseClassWrap : public BaseClass{
     public:
        BaseClassWrap( PyObject* self_, const std::string& name)
             : BaseClass(name),self(self_) { Py_INCREF(self); }
         BaseClassWrap( PyObject* self_, const BaseClass& copy ) : 
BaseClass(copy), self(self_) { Py_INCREF(self); }
         ~BaseClassWrap() { Py_DECREF(self); }

         PyObject *self;
     };

Wrapped BaseClass
------------------------------------
class_<BaseClass, shared_ptr<BaseClassWrap> >("BaseClass",
             init<const std::string&>())
             .add_property("name", make_function(&BaseClass::getName, 
return_value_policy<copy_const_reference>()) );

// both needed for using shared_ptr's together with the wrapper-class
register_ptr_to_python<shared_ptr<BaseClass> >();    // to_python converter
implicitly_convertible<shared_ptr<BaseClassWrap>, shared_ptr<BaseClass> >();

Subclass
------------------------------------
class Subclass(BaseClass):
     def __init__(self, name):
         BaseClass.__init__(self, name)
         self.foo = "bar"

------------------------------------------------------------------------------

Imagine the following Python code:

obj = SubClass("superclass")
BaseClassManager.addObject(obj)

# and somewhere else

obj = BaseClassManager.getObjectByName("superclass")
print obj.name     # prints "superclass" as expected
print obj.foo         # AttributeError: 'BaseClass' object has no 
attribute 'foo'

Seems all attributes got lost, be it a member-variable or methods I 
defined in SubClass. Strangely obj is in both cases the same pointer (f. 
ex. "SubClass object at 0x02343345").

Is there something I can do to preserve the attributes? Otherwise it is 
kind of senseless to extend a C++ class in Python if it can't have its 
own attributes.

Thanks a lot for the help.

Cheers.



More information about the Cplusplus-sig mailing list