[C++-sig] Re: Doubts with wrapping/using abstract bases.

Raoul Gough RaoulGough at yahoo.co.uk
Tue Aug 12 02:15:33 CEST 2003


Prabhu Ramachandran <prabhu at aero.iitm.ernet.in> writes:

>>>>>> "N" == nicodemus  <nicodemus at globalite.com.br> writes:
[snip Pyste code, etc...]
>
> Here is the error that I get when I run this script with holder.so
> compiled using gcc 2.95.4 with boost CVS (from this morning) with the
> libboost*.so compiled and Pyste from CVS.
>
> B::f
> B::f
> Traceback (most recent call last):
>   File "test_holder.py", line 8, in ?
>     x.f()
> Boost.Python.ArgumentError: Python argument types in
>     B.f(B)
> did not match C++ signature:
>     f(Q227_GLOBAL_.N.holder.cppYtV9Va9B_Wrapper {lvalue})
>     f(1B {lvalue})

Might help for you to demangle that symbol, but I would guess the
problem is somehow related to A_Wrapper and B_Wrapper being
incompatible. They share a common base class, A, but that probably
doesn't help here. Let's see if I understand this (any or all of this
could be wrong!) ...

[reordered from above]
> // ------------------ test_holder.py ----------------
> import holder
> b = holder.B()

Here type(b) is <class 'holder.B'> and b actually contains a
std::auto_ptr<B_Wrapper>.

> b.f()

this calls B.f from Python, which goes to B_Wrapper::default_f in C++
and then to B::f

> holder.func(b) 
> h = holder.Holder ()
> h.add(b)

This uses add_wrapper which upcasts the B_Wrapper * to an A * and
inserts it into the container. Note that it also releases() the value
from the std::auto_ptr<B_Wrapper> in b, so any subsequent b.f() call
will fail. Is this really what you want?

> b1 = h.get(0)

h.get(0) returns an A* on the C++ side, which gets returned to Python
as an A_Wrapper ("print type(b1)" gives <class 'holder.A'>)

> b1.f()

This call A.f on the python side, which (via virtual dispatch) calls
B_Wrapper::f() on the C++ side, since the A* really points to the
original B_Wrapper object. B_Wrapper::f() then attempts
call_method<void>(self, "f") which is what is failing:

> Boost.Python.ArgumentError: Python argument types in
>     B.f(B)
> did not match C++ signature:
>     f(Q227_GLOBAL_.N.holder.cppYtV9Va9B_Wrapper {lvalue})
>     f(1B {lvalue})

Don't really understand why this is happending. The "self" object
passed to call_method will probably be of type holder.A (since that
was the type returned to Python from h.get(0)). Can anybody take it
from here?

BTW, have you considered using boost::shared_ptr? I wouldn't trust
std::auto_ptr with this kind of stuff. Also, storing raw pointers in a
vector is just asking for trouble if you ask me.

-- 
Raoul Gough
"Let there be one measure for wine throughout our kingdom, and one
measure for ale, and one measure for corn" - Magna Carta





More information about the Cplusplus-sig mailing list