Dear Karl,
the problem is fixed if you do the following:
bp::class_<BaseWrapper, boost::noncopyable>("Base", bp::no_init)
.def("do_stuff", bp::pure_virtual(&BaseWrapper::do_stuff))
.def("name", &BaseWrapper::name, &BaseWrapper::default_name)
.def("name", &Base::name)
;
bp::class_<DerivedWrapper, bp::bases<Base> >("Derived")
.def("do_stuff", &DerivedWrapper::do_stuff,
&DerivedWrapper::default_do_stuff)
.def("name", &DerivedWrapper::name,
&DerivedWrapper::default_name)
.def("name", &Derived::name)
;
Note the two added definitions of `name`.
Why is that needed?
>>> t = testInheritance.Third(testInheritance.Derived())
her in reality an instance of DerivedWrapper is created, and then
passed to C++. When you then do `t.get_base()` and instance of
DerivedWrapper will be returned (there is actually some "magic" going
on that boost python can associate your `boost::shared_ptr<Base>` with
the PyObject that is a DerivedWrapper). Because that object is a
`DerivedWrapper` the `.name` calls DerivedWrapper::name.
In your second example the object is create with the call `_base =
boost::shared_ptr<Base>(new Derived());`. This class is no subclass of
`DerivedWrapper` nor `BaseWrapper`, so you can not call a member
function of the wrappers. That is why you get the error.
By exporting
.def("name", &Base::name)
you are able to call name if you have no Wrapper.
The reason why you have to do
.def("name", &DerivedWrapper::name,
&DerivedWrapper::default_name)
.def("name", &Derived::name)
in the derived class is that the first definition overrides both
definitions for `&BaseWrapper::name` and `&Base::name`
-Holger
On Tue, Sep 4, 2012 at 7:40 PM, Charly Bicker <[email protected]> wrote:
> Dear all,
>
> first of all thanks to Holger for pointing me to a workaround with the
> add_static_property problem!
>
> Unfortunately, I already ran into the next problem, which seems very weird to
> me:
>
> I have again my old friends Base and Derived, with the obvious inheritance
> (source file attached). Now, there is a third class, named "Third", which has
> as a data member a boost::shared_ptr<Base> which is initialized in the
> constructor. For this reason, the constructor takes such a pointer as an
> argument.
>
> Now, the point where stuff goes wrong is this: the argument to the
> constructor has as a default value a NULL-boost::shared_ptr<Base>. The
> behavior now works as expected if the argument is provided in python:
>
>>>> import testInheritance
>>>> t = testInheritance.Third(testInheritance.Derived())
>>>> t.get_base().name()
> 'Derived'
>>>>
>
> However, this fails if one does not provide an argument:
>
>>>> t = testInheritance.Third()
>>>> t.get_base().name()
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> Boost.Python.ArgumentError: Python argument types in
> Derived.name(Derived)
> did not match C++ signature:
> name(DerivedWrapper {lvalue})
> name(DerivedWrapper {lvalue})
>>>>
>
> I cannot wrap my head around this, can anybody point me to what I am doing
> wrong? I would be very grateful!
>
> Best regards,
> Karl Bicker
>
> _______________________________________________
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
_______________________________________________
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig