[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