【问题标题】:Boost.Python: how to create & return a list of existing c++ objects, no copyingBoost.Python:如何创建和返回现有 c++ 对象的列表,无需复制
【发布时间】:2013-12-09 19:16:33
【问题描述】:

我正在使用 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 对象的指针),但我我愿意接受这个限制。

【问题讨论】:

    标签: c++ python boost boost-python


    【解决方案1】:

    一种方法是公开两个类:

    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>
    

    【讨论】:

    • 谢谢,但我希望有更多带有列表界面的pythonic。
    • @GaryO 好的,但请注意,您可以很容易地将其更改为 python 列表:l = [get_thing(c, i) for i in xrange(c.n_things)]
    • 我试过这个,它基本上可以工作,但如果我尝试get_thing(c, i)==get_thing(c, i),它会返回 False。它不应该返回对现有对象的引用并因此返回 True 吗?
    • @GaryO 这是因为它们不是同一个对象,boost::python 使用了一个技巧来返回对对象的引用,boost.org/doc/libs/1_55_0/libs/python/doc/v2/…(请参阅解释并查看最后一个示例)
    • 为了比较对象,您应该实现运算符 eq,正如此处 [stackoverflow.com/questions/10612218/… @grivescorbett 指出的那样。 (但你应该比较两个指针而不是一个 shared_ptr 和一个指针)。
    猜你喜欢
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多