[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 );

    // 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:


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 

    // Declare the CWheel extension class
    object wheel_class =
            .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,

More information about the Cplusplus-sig mailing list