Size: 2827
Comment: creating Python objects from C++
|
Size: 3048
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 75: | Line 75: |
---- 4. ''How to I expose static class data members ?'' {{{ object x_class = class_<X>("X") .def( ... ) ... ; x_class.attr("fu") = X::fu; x_class.attr("bar") = X::bar; ... }}} |
From comp.python.c++ newsgroup:
1. The constructors of some classes I am trying to wrap are private because instances must be created by using a factory. Is it possible to wrap such classes using bpl v2?
Sure. Of course you can only create the instances using the factory...
If you look at libs/python/test/test_pointer_adoption.cpp you'll see the factory function "create" is being used to generate new instances of class A. It uses return_value_policy<manage_new_object> to instruct Python to adopt the A* to hold the instance.
A* create(std::string const& s) { return new A(s); } BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) { def("num_a_instances", num_a_instances); // Specify the manage_new_object return policy to take // ownership of create's result def("create", create, return_value_policy<manage_new_object>()); class_<A>() .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) ; }
2. What is the relation between this no_init and boost::noncopyable?
The only relationship is that they both deal with constructors.
no_init means "do not try to define a Python init function"
noncopyable means "do not try to register a converter which can convert C++ T return values to python".
3. 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 (Lets 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.
4. How to I expose static class data members ?
object x_class = class_<X>("X") .def( ... ) ... ; x_class.attr("fu") = X::fu; x_class.attr("bar") = X::bar; ...