[C++-sig] Type conversion problem -- simplified
David Abrahams
dave at boost-consulting.com
Sun Nov 5 19:59:08 CET 2006
Randall Hopper <viznut at charter.net> writes:
> David Abrahams:
> |Randall Hopper <viznut at charter.net> writes:
> |> The puzzling thing about all this is, when I create an osg.Vec3Array inside
> |> of Python, then I can call methods (such as __getitem__, set, etc.) on that
> |> Vec3Array from inside Python with no problem.
> |>
> |> But if I obtain a reference to a Vec3Array (e.g. returned from that
> |> Geometry::getVertexArray() API above) which was generated internal to
> |> OpenSceneGraph), then I get the error message I mentioned previously.
> |
> |When you pass both kinds of Python Vec3Array object to type(), do you
> |see the same thing in both cases?
>
> Yes:
>
> <class 'PyOSG.osg.Vec3Array'>
>
> |> This makes me thing something isn't being correctly done inside that
> |> "manage_osg_object" return policy, but I have no clue what that is
> |> yet.
> |
> |What is the return type of get_pointer(x) where x is an
> |osg::ref_ptr<T>?
>
> (T *). Here's the relevent code:
>
> namespace osg {
>
> template<class T> inline T * get_pointer(osg::ref_ptr<T> const & p)
> {
> return const_cast<T *>(p.get());
> }
>
> }
>
>
> By the way, all efforts so far to trim down the code have been too sweeping
> to keep the problem. So I'm still binary searching to get even get a small
> test program.
>
> I wish I had some understanding of what the problem is so I could focus my
> efforts. Could you give me your perception of what it is?
>From
Traceback (most recent call last):
...
File "osg_to_sgg.py", line 153, in setupGeode
v[0].set( 0, 1, 2 )
Boost.Python.ArgumentError: Python argument types in
Vec3Array.__getitem__(Vec3Array, int)
did not match C++ signature:
__getitem__(osg::TemplateArray<osg::Vec3f, (osg::Array::Type)10, 3, 5126>*, int)
it's pretty clear that attempt to extract a
osg::TemplateArray<osg::Vec3f, (osg::Array::Type)10, 3, 5126>*
from the v in the Python expression v[0] failed.
Why it failed is a mystery. Certainly the 2nd argument matches,
though, so you could reduce this to the problem of pass v to a wrapped
C++ function with the signature
void f(Vec3Array*)
When a Python instance of a wrapped class T is converted to a T*,
Boost.Python searches through the list of instance_holders (plural, to
support MI) held by the Python instance for one that contains a T.
See find_instance_impl in libs/python/src/object/class.cpp
In your case the search is failing where it should succeed. I would
expect you to have a single instance_holder in the chain that is in
fact a python::objects::pointer_holder containing a
ref_ptr<Vec3Array>. The only reasons I can think of for the match to
fail are:
a. some problem with typeid matching.
b. the ref_ptr is in fact NULL.
I think you could examine the execution of find_instance_impl in a
debugger and learn a lot.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list