从返回shared_ptr的函数返回相同的底层Python boost :: python :: object

时间:2012-12-28 23:59:23

标签: boost-python

在我的应用程序中,我通过boost :: python。

通过boost :: shared_ptr包装C ++对象

我遇到的问题是,无论何时我在C ++中返回引用,boost都会分配一个新对象来指向引用,而不是重用现有的Python对象。除此之外,这会打破可能在Python中设置的相等测试和自定义属性。

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

示例代码:

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

3 个答案:

答案 0 :(得分:0)

您需要按如下方式定义:

class_<Apple>("Apple", no_init)
    .def("__init__", make_constructor(getMoldyApple))
;

答案 1 :(得分:0)

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

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

答案 2 :(得分:-1)

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

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