Как проверить идентичность обернутых в C ++ объектов boost-python? - PullRequest
0 голосов
/ 11 июня 2019

Я использую 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
...