1755
Comment: Added "static" keyword to create() definition
|
2824
Clarification
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
Since Python handles memory allocation and garbage collection automatically, the concept "pointer" is not meaningful within Python. However, many C++ API exposes either raw pointers or shared pointers, and to wrap such APIs one would need to deal with pointers. | Since Python handles memory allocation and garbage collection automatically, the concept of a "pointer" is not meaningful in Python. However, many C++ APIs expose either raw pointers or shared pointers, to wrap these APIs we need to deal with pointers. |
Line 5: | Line 5: |
=== Pointers (raw C++ pointers) === | === Raw C++ Pointers === |
Line 7: | Line 7: |
The life time of C++ objects created by "new A" kan be handled by Pythons garbage collection by using the {{{manage_new_object}}} storage policy: | The lifetime of C++ objects created by {{{new A}}} can be handled by Python's garbage collection by using the {{{manage_new_object}}} return policy: |
Line 9: | Line 9: |
{{{struct A { | {{{ struct A { |
Line 17: | Line 18: |
.def("create",&A::create,return_value_policy<manage_new_object>()) | .def("create",&A::create, return_value_policy<manage_new_object>()) |
Line 33: | Line 34: |
Smart pointers, e.g. boost::shared_ptr<T>, is another common way to give away ownership of objects in C++. Theese kind of smart pointer are automatically handled, if you declare their existence, when declaring the class to boost.python. |
The usage of smart pointers (e.g. {{{boost::shared_ptr<T>}}}) is another common way to give away ownership of objects in C++. These kinds of smart pointer are automatically handled if you declare their existence when declaring the class to boost::python. This is done by including the holding type as a template parameter to {{{class_<>}}}, like in the following example: |
Line 37: | Line 36: |
E.g. | {{{ #include <string> #include <boost/shared_ptr.hpp> #include <boost/python.hpp> |
Line 39: | Line 41: |
{{{#include <boost/shared_ptr.h> | |
Line 41: | Line 42: |
using namespace std; using namespace boost::python; |
|
Line 58: | Line 61: |
Line 63: | Line 67: |
=== Smart Pointer Example with OpenSceneGraph === The Node.cpp file: {{{ #include <boost/python.hpp> #include <osg/ref_ptr> #include <osg/Node> using namespace boost::python; using namespace osg; // Tag the OpenSceneGraph ref_ptr type as a smart pointer. namespace boost { namespace python { template <class T> struct pointee< ref_ptr<T> > { typedef T type; }; }} // Declare the actual type BOOST_PYTHON_MODULE(Node) { class_<Node, ref_ptr<Node> >("Node") ; } }}} This creates an opaque Node pointer. The only thing a Python app can do with it is move Node pointers between C++ modules. For that application, the module must still be imported by the Python app. If Node.pyd is in a package directory, importing it in the __init__.py file in that directory seems to be a simple, workable solution. |
Pointers and smart pointers
Since Python handles memory allocation and garbage collection automatically, the concept of a "pointer" is not meaningful in Python. However, many C++ APIs expose either raw pointers or shared pointers, to wrap these APIs we need to deal with pointers.
Raw C++ Pointers
The lifetime of C++ objects created by new A can be handled by Python's garbage collection by using the manage_new_object return policy:
struct A { static A* create () { return new A; } std::string hello () { return "Hello, is there anybody in there?"; } }; BOOST_PYTHON_MODULE(shared_ptr) { class_<A>("A",no_init) .def("create",&A::create, return_value_policy<manage_new_object>()) .staticmethod("create") .def("hello",&A::hello) ; }
A sample python program:
from pointer import * an_A = A.create() print an_A.hello()
Smart pointers
The usage of smart pointers (e.g. boost::shared_ptr<T>) is another common way to give away ownership of objects in C++. These kinds of smart pointer are automatically handled if you declare their existence when declaring the class to boost::python. This is done by including the holding type as a template parameter to class_<>, like in the following example:
#include <string> #include <boost/shared_ptr.hpp> #include <boost/python.hpp> using namespace boost; using namespace std; using namespace boost::python; struct A { static shared_ptr<A> create () { return shared_ptr<A>(new A); } std::string hello () { return "Just nod if you can hear me!"; } }; BOOST_PYTHON_MODULE(shared_ptr) { class_<A, shared_ptr<A> >("A",init<>()) .def("create",&A::create ) .staticmethod("create") .def("hello",&A::hello) ; }
A sample python program:
from shared_ptr import * an_A = A.create() print an_A.hello()
Smart Pointer Example with OpenSceneGraph
The Node.cpp file:
#include <boost/python.hpp> #include <osg/ref_ptr> #include <osg/Node> using namespace boost::python; using namespace osg; // Tag the OpenSceneGraph ref_ptr type as a smart pointer. namespace boost { namespace python { template <class T> struct pointee< ref_ptr<T> > { typedef T type; }; }} // Declare the actual type BOOST_PYTHON_MODULE(Node) { class_<Node, ref_ptr<Node> >("Node") ; }
This creates an opaque Node pointer. The only thing a Python app can do with it is move Node pointers between C++ modules. For that application, the module must still be imported by the Python app. If Node.pyd is in a package directory, importing it in the init.py file in that directory seems to be a simple, workable solution.