Boost.Python:如何创建&返回现有c ++对象的列表,不复制

时间:2013-12-09 19:16:33

标签: c++ python boost boost-python

我正在使用Boost.Python来公开另一个类中的对象数组:

class Thing {
  int i; // and of course other stuff
};

class Container {
  Thing *things[128];
  int n_things;
}

我想向python提供一个只读列表接口。我在boost.python扩展源代码中有这样的东西:

static bp::list EXTget_things(Container &c)
{
  bp::list thing_list;
  for (int i = 0; i < c.n_things; i++) {
    thing_list.append(c.things[i]);
  }
  return thing_list;
}

我还有(不寻常的?)约束,我无法复制Thing对象。他们没有工作的复制构造函数,我无法真正改变它。我想返回一个包含原始对象地址的python列表,并相应地确保python在释放列表时不会释放原始文件。

我该怎么做? (或者可以这样做吗?)我认识到如果Container在python中超出范围会导致生命周期问题,但是其他一些python代码仍然试图使用param_list(因为它有指向Collection对象的指针),但是我我愿意接受这种限制。

1 个答案:

答案 0 :(得分:2)

一种方法是公开这两个类:

class_<Thing>("thing")
    .def_readwrite("i", &Thing::i)
;

class_<Container>("container")
    .def_readwrite("n_things", &Container::n_things)
;

然后创建一个返回对Thing的引用的方法:

Thing& get_thing(Container& c, size_t index)
{
    return *c.things[index];
}

最后,你应该公开这个功能:

def("get_thing", get_thing, return_value_policy<reference_existing_object>());

并且你可以迭代它:

c = mylib.container()
for i in xrange(c.n_things):
    thing = get_thing(c, i)
    thing.i = <INT_VALUE>