Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost.Python return python object which references to existing c++ objects

Suppose I want to get the reference to some global / internal c++ object, one method is to declare function with boost::python::return_value_policy<reference_existing_object>().

Both GetGlobalObjectA and GetGlobalObjectB return the reference to the original c++ object without create a new copy;

But how to make GetGlobalObjectByID return a ref to the existing c++ object?

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_&ltA&gt("A");
    class_&ltB&gt("B");

    def("GetGlobalObjectByID", GetGlobalObjectByID);

    def("GetGlobalObjectA", GetGlobalObjectA, return_value_policy&ltreference_existing_object&gt());
    def("GetGlobalObjectB", GetGlobalObjectB, return_value_policy&ltreference_existing_object&gt());

}

like image 467
lostyzd Avatar asked Apr 06 '18 11:04

lostyzd


1 Answers

Based on this answer, I found it is possible to use reference_existing_object::apply as a converter.

template &lttypename T&gt
inline object MagicMethod(T* ptr)
{
    typename reference_existing_object::apply::type converter;

    handle handle(converter(ptr));

    return object(handle);
}

And here is the modified version.

boost::python::object GetGlobalObjectByID(int id)
{
    if (id == 1)
        return MagicMethod(&globalA);
    else if (id == 2)
        return MagicMethod(&globalB);
    else
        return boost:python::object();
}
like image 129
lostyzd Avatar answered Nov 02 '22 06:11

lostyzd