1

在我的应用程序中,我通过 boost::shared_ptr 通过 boost::python 包装 C++ 对象。

我遇到的问题是,每当我在 C++ 中返回一个引用时,boost 都会分配一个新对象来指向该引用,而不是重用现有的 Python 对象。除其他外,这破坏了可能已在 Python 中设置的相等测试和自定义属性。

每次我给它一个指向同一个底层对象的 shared_ptr 时,是否有一种干净、简单的方法可以让 boost::python 自动重用现有的 boost::python::object(或至少 PyObject)?

示例代码:

C++:

#include <boost/python.hpp>
using namespace boost::python;

class Apple {};

boost::shared_ptr<Apple> theMoldyApple(new Apple());

boost::shared_ptr<Apple> getMoldyApple() {
    //pretend we do some logic here that won't always return theMoldyApple 
    //exactly
    return theMoldyApple;
}

BOOST_PYTHON_MODULE(bobtest) {
    class_<Apple, boost::shared_ptr<Apple>>("Apple", init<>());

    def("getMoldyApple", getMoldyApple);
}

Python:

from bobtest import *

# Set a custom property on the Python object:
ma = getMoldyApple()
ma.customProp = 11

# This works fine because ma is the same PyObject is was above:
print "ma.customProp:", ma.customProp

# This doesn't work because boost::python wraps a copy of the shared_ptr
# (that points to theMoldyApple) with a new PyObject each time I call
# getMoldyApple()
print "getMoldyApple().customProp:", getMoldyApple().customProp

结果:

ma.customProp: 11
getMoldyApple().customProp:
Traceback (most recent call last):
  File "<string>", line 14, in <module>
AttributeError: 'Apple' object has no attribute 'customProp'

期望的结果:

ma.customProp: 11
getMoldyApple().customProp: 11
4

3 回答 3

0

您需要按如下方式定义它:

class_<Apple>("Apple", no_init)
    .def("__init__", make_constructor(getMoldyApple))
;
于 2014-01-16T07:56:34.903 回答
0

您需要创建一个包含 Python 对象的包装类,并使用has_back_reference.

http://www.boost.org/doc/libs/1_55_0/libs/python/doc/v2/has_back_reference.html

于 2015-01-21T12:16:36.873 回答
-1

我在代码审查中发布了一个使用自定义转换器和地图作为缓存的通用解决方案:

https://codereview.stackexchange.com/questions/130044/same-pyobject-for-a-shared-ptr-c-object

于 2016-06-10T14:25:37.533 回答