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

Boost.Python: how to create & return a list of existing c++ objects, no copying

本文关键字:对象 列表 复制 返回 何创建 Python 创建 Boost      更新时间:2023-10-16

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

class Thing {
  int i; // and of course other stuff
};
class Container {
  Thing *things[128];
  int n_things;
}

我想为python提供一个到Things的只读列表接口。我的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对象的指针),但我愿意处理这个限制。

一种方法是公开两个类:

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>