[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