[C++-sig] How to create instance using existing C++ object

Vladimir Ofitserov vladimir at inktomi.com
Wed Feb 1 05:37:38 CET 2006


Let say I have a C++ function that gets instance of noncopyable object 
(CDoc for example) and I want to implement this function in python 
module, wrapping CDoc class using Boost.Python:

void MyFunction( CDoc *pDoc ) {

    // want a wrapper that is just a pointer/reference/shared_ptr
    class_<CDoc, CDoc&, noncopyable> cdoc( "CDoc", noinit );
    cdoc.def(...);
    cdoc.def(...);

    // now how do I create instance of "cdoc" around pDoc
    // using cdoc::operator()?
    object odoc = cdoc( *pDoc );

    // calling python module with new object instance
    call_method<void>( pymodule, "myfunction", odoc );
}

The main problem is that I could not find any documentation on how to 
create python wrapper around existing object. Only thing I've seen is 
Python Wiki FAQ article that has correct problem statement but 
*incorrect* answer:

http://wiki.python.org/moin/boost.python/FAQ


-------------------------------------------
Is it is possible to convert pointers to existing classes to
PyObjects* and then be able to pass an existing instance of an
object directly to and from python?

It is.

Example: In C++ I create a CWheel and I set its member m_diameter to 
1233. In python I have a function that receives a CWheel and displays 
the diameter (Let's suppose that Python knows the CWheel from Boost.Python):

def printCWheelDiam(awheel):
    print awheel.m_diameter

The safest thing to do is to create the CWheel by invoking its class 
wrapper:

    // Declare the CWheel extension class
    object wheel_class =
        class_<CWheel>("CWheel")
            .def_readonly("m_diameter", &CWheel::m_diameter)
            .def("some_member_function", &CWheel::some_member_function)
            ...
            ;

    object wheel_obj = wheel_class(); // construct one

Now you can pass wheel_obj back to python, and all reference counts are 
nicely managed. You don't need to "map" anything between C++ and Python; 
the library takes care of that for you.

If you really want to pass pointers around, it's certainly possible to 
tell the library to build a Python object around the pointer, but then 
you need to make sure the lifetime of the C++ object being referenced by 
the pointer extends past the lifetime of all Python references to the 
object or your program will crash.

--------------------------------------------------------------------------------------

This answer above is no way match to the question because there is *new* 
object created (wheel_obj) using default constructor and it no way an 
*existing* object as was asked in the question. The last paragraph says 
exactly what I want but it only mentions that "it's certainly possible 
to tell the library to build a Python object around pointer" but I must 
be really stupid because I just can figure out how :-)

Thanks for help,
-vladimir




More information about the Cplusplus-sig mailing list