[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