[C++-sig] Re: extracting C++ objects

David Abrahams dave at boost-consulting.com
Mon Jul 19 04:28:08 CEST 2004


James Mastro <jmastro at rochester.rr.com> writes:

> At 06:24 PM 7/18/2004, you wrote:
>
>>Jim, I think you'd better try posting in plaintext.
>
> Oops. You'd think C++ comments showing up in red in Eudora would have
> been a good clue that something was up. This should be OK. Sorry about
> that.
>
> My problem is I can't extract a C++ object out of a Python
> object. MyPoint is a simple class storing doubles for x and
> y. SomeObject is an object onscreen, location is its location. Here's
> the Python:
>
> import JimsModule       #where the wrapped MyPoint is
>
> class SomeObject:
>
>      def __init__(self):
>          self.num = 942
>          self.location = JimsModule.MyPoint( 3.2, -4.7 )
>
>      def getPt(self):
>          return self.location
>
>      def getX(self):
>          return self.location.x
>
> Here's the C++:
>
> handle<> (PyImport_ImportModule( "SomeObject" ) );  // SomeObject class is in SomeObject.py module
> handle<> module( borrowed( PyImport_AddModule( "SomeObject" ) ) );
> handle<> the_namespace(borrowed( PyModule_GetDict(module.get()) ));
> object the_class( 
>             borrowed( PyDict_GetItemString(the_namespace.get(), "SomeObject") ));

I'm a little surprised that compiles ( and do you really need to do
PyImport_AddModule?), but anyway, you should do:

object module( 
        handle<>( borrowed( PyImport_AddModule( "SomeObject" ) ) ) );

object the_class = module.attr("SomeObject");

> object  obj = the_class();
>
> handle<> a( PyObject_CallMethod( obj.ptr(), "getX", NULL ) );

Bleah.  Should be:

  object a = obj.attr("getX")();

> double  val = extract<double>( a.get() );                       // returns 3.2

surprised this compiles too.

  double val = extract<double>(a);

is better.

> int     num = extract<int>(obj.attr("num"));            // returns 942

Hooray!

> So I can extract POD fine. But what about getting my C++ MyPoint object out?
>
> extract<MyPoint&> ck(obj.attr("location"));
> if ( ck.check() ) {
>      MyPoint&    myPt = extract<MyPoint&>(obj.attr("location"));

Bleah. Should be:

       MyPoint& myPt = ck();
> }
>
> ck.check() returns false, and ignoring it and attempting the
> extraction anyway throws an exception saying "TypeError: No registered
> converter was able to extract a C++ reference to type class MyPoint
> from this Python object of type MyPoint". 

1. Did you wrap MyPoint with class_<MyPoint> and has the extension
   module that does that wrapping been loaded at this point?

2. Does it work if you do it in two steps?

   object pt = obj.attr("location");
   MyPoint& myPt = extract<MyPoint&>(pt);
   
> Using the getPt method with
> call_method, etc, gave me the same error. Trying to get a MyPoint
> object, or a MyPoint* out gives me similar errors.
>
> How can I pull my C++ object out of the Python object?

If all this fails, please post a minimal but complete reproducible
example (as an attachment).

Thanks,
-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com




More information about the Cplusplus-sig mailing list