作者:华亮 地址:http://blog.csdn.net/cedricporter
我们有一段C++代码
A aaa; A& DoSomethingWithA( int a ) { aaa.Set( 12 ); return aaa; //return &aaa; } // BOOST_PYTHON_MODULE( Haha ) { using namespace boost::python; class_< A >( "A", "Lala" ) .def( "Set", &A::Set, arg("c") ) .def_readwrite( "b", &A::b ); def( "DoSomethingWithA", DoSomethingWithA, arg("a"), return_value_policy<reference_existing_object>() ); }
一段Python
a = DoSomethingWithA( 5 ) def do(): return a.b;
boost::python::object main_module = boost::python::import("a"); object dofoo = main_module.attr("do"); std::cout << extract<int>( dofoo() );
关键问题所在是
def( "DoSomethingWithA", DoSomethingWithA, arg("a"), return_value_policy<reference_existing_object>() );
下面这段文字从http://wiki.python.org/moin/boost.python/CallPolicy#return_value_policy.3CT.3E拷贝过来的。有空再翻译了。
with T one of:
naïve (dangerous) approach
boost.python/ResultConverterGenerator which can be used to wrap C++ functions returning a reference or pointer to a C++ object.
When the wrapped function is called, the value referenced by its return value is not copied.
A new Python object is created which contains an unowned U* pointer to the referent of the wrapped function's return value, and no attempt is made to ensure that the lifetime of the referent is at least as long as that of the corresponding Python object.
This class is used in the implementation of return_internal_reference. Also NULL pointer returning as None.
BoostPython v1 approach
BoostPython/ResultConverterGenerator which can be used to wrap C++ functions returning a pointer to an object allocated with a new-expression and expecting the caller to take responsibility for deleting that C++ object from heap. boost.python will do it as part of Python object destruction.
Use case:
T* factory() { return new T(); } class_<T>("T"); def("Tfactory", factory, return_value_policy<manage_new_object>() );
boost.python/ResultConverterGenerator which can be used to wrap C++ functions returning any reference or value type.
The return value is copied into a new Python object.