Boost.Python返回引用现有c ++对象的python对象

时间:2018-04-06 11:49:51

标签: python c++ boost boost-python

假设我想获得对某些全局/内部c ++对象的引用,一种方法是使用boost::python::return_value_policy<reference_existing_object>()声明函数。

GetGlobalObjectAGetGlobalObjectB都返回对原始c ++对象的引用,而不创建新副本;

但是如何使GetGlobalObjectByID返回对现有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>());

}

1 个答案:

答案 0 :(得分:1)

根据此answer,我发现可以使用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();
}