Я использую boost :: python для переноса функции C ++, которая возвращает указатель на существующий объект C ++, также упакованный в bp.При вызове функции из Python каждый раз возвращается новый объект Python, даже если все они ссылаются на один и тот же экземпляр C ++.
Есть ли способ проверить, удерживают ли два экземпляра boost.python один и тот же объект C ++?
Для определенного класса C ++ C
это можно сделать, используя extract<C*>(pyobj)
для двух объектов python для сравнения их указателей C ++.Однако это будет работать только для типа C
и должно быть определено отдельно для каждого поддерживаемого класса C ++.
Кажется, что все классы boost.python наследуются от Boost.Python.instance
.Было бы предпочтительно иметь одну is_identical
функцию, которая могла бы проверять идентичность для любой пары Boost.Python
объектов.
Вот минимальный код boost :: python, который определяет функцию geta()
, которая всегда возвращаеттот же экземпляр C ++.
// cppidentity.cpp
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
using namespace boost::python;
struct A { int a; };
A a_instance;
A* geta() { return &a_instance; }
BOOST_PYTHON_MODULE(cppidentity)
{
class_<A>("A")
.def_readwrite("a", &A::a);
def("geta", &geta,
return_value_policy<reference_existing_object>());
}
Результаты geta()
содержат тот же объект C ++, но в Python выглядят иначе:
from cppidentity import geta
a0 = geta()
a1 = geta()
print(f"(a0.a, a1.a) = {(a0.a, a1.a)}")
print("setting a0.a = 13 ..."); a0.a = 13
print(f"(a0.a, a1.a) = {(a0.a, a1.a)}")
print(f"(a0 is a1) = {a0 is a1} (a0 == a1) = {a0 == a1}")
output
(a0.a, a1.a) = (0, 0)
setting a0.a = 13 ...
(a0.a, a1.a) = (13, 13)
(a0 is a1) = False (a0 == a1) = False