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 <legord...@gmx.net> 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
> Cplusplus-sig@python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to