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_<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>());
}
Based on this answer, I found it is possible to use reference_existing_object::apply as a converter.
template <typename T>
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With