Boost.Python return python 引用现有 C++ 对象的对象
Boost.Python return python object which references to existing c++ objects
假设我想获取对某些全局/内部 C++ 对象的引用,一种方法是使用 boost::python::return_value_policy<reference_existing_object>()
.
声明函数
GetGlobalObjectA
和GetGlobalObjectB
return均引用原始c++对象而不创建新副本;
但是如何使 GetGlobalObjectByID
return 成为现有 c++ 对象的引用?
struct A { uint32_t value; };
struct B { uint64_t value; };
A globalA;
B globalB;
boost::python::object GetGlobalObjectByID(int id)
{
// boost::python::object will return a new copy of C++ object, not the global one.
if (id == 1)
return boost::python::object(&globalA);
else if (id == 2)
return boost::python::object(&globalB);
else
return boost::python::object(nullptr);
}
A& GetGlobalObjectA() { return globalA; }
B& GetGlobalObjectB() { return globalB; }
BOOST_PYTHON_MODULE(myModule)
{
using namespace boost::python;
class_<A>("A");
class_<B>("B");
def("GetGlobalObjectByID", GetGlobalObjectByID);
def("GetGlobalObjectA", GetGlobalObjectA, return_value_policy<reference_existing_object>());
def("GetGlobalObjectB", GetGlobalObjectB, return_value_policy<reference_existing_object>());
}
基于此,我发现可以使用reference_existing_object::apply
作为转换器。
template <typename T>
inline object MagicMethod(T* ptr)
{
typename reference_existing_object::apply::type converter;
handle handle(converter(ptr));
return object(handle);
}
这里是修改后的版本。
boost::python::object GetGlobalObjectByID(int id)
{
if (id == 1)
return MagicMethod(&globalA);
else if (id == 2)
return MagicMethod(&globalB);
else
return boost:python::object();
}
假设我想获取对某些全局/内部 C++ 对象的引用,一种方法是使用 boost::python::return_value_policy<reference_existing_object>()
.
GetGlobalObjectA
和GetGlobalObjectB
return均引用原始c++对象而不创建新副本;
但是如何使 GetGlobalObjectByID
return 成为现有 c++ 对象的引用?
struct A { uint32_t value; }; struct B { uint64_t value; }; A globalA; B globalB; boost::python::object GetGlobalObjectByID(int id) { // boost::python::object will return a new copy of C++ object, not the global one. if (id == 1) return boost::python::object(&globalA); else if (id == 2) return boost::python::object(&globalB); else return boost::python::object(nullptr); } A& GetGlobalObjectA() { return globalA; } B& GetGlobalObjectB() { return globalB; } BOOST_PYTHON_MODULE(myModule) { using namespace boost::python; class_<A>("A"); class_<B>("B"); def("GetGlobalObjectByID", GetGlobalObjectByID); def("GetGlobalObjectA", GetGlobalObjectA, return_value_policy<reference_existing_object>()); def("GetGlobalObjectB", GetGlobalObjectB, return_value_policy<reference_existing_object>()); }
基于此reference_existing_object::apply
作为转换器。
template <typename T> inline object MagicMethod(T* ptr) { typename reference_existing_object::apply::type converter; handle handle(converter(ptr)); return object(handle); }
这里是修改后的版本。
boost::python::object GetGlobalObjectByID(int id) { if (id == 1) return MagicMethod(&globalA); else if (id == 2) return MagicMethod(&globalB); else return boost:python::object(); }