[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