【问题标题】:wrap std::vector<pointer*> in boost.python在 boost.python 中包装 std::vector<pointer*>
【发布时间】:2011-07-27 17:55:27
【问题描述】:

根据我的研究,包装包含指针类型的 std::vector 似乎不是很简单。例如:

std::vector<GameObject*>

我查看了 boost python vector_index_suite,但它只是给了我运行时错误:

TypeError: No to_python (by-value) converter found for C++ type: 游戏对象*

我已经暴露了GameObject:

class_<GameObject>("GameObject") ...

所以据我了解,开箱即用的解决方案是不可能的。我必须做某种包装?有人能帮我弄清楚我应该从哪里开始吗?

【问题讨论】:

    标签: c++ pointers vector containers boost-python


    【解决方案1】:

    解决此问题的方法是明确声明您的类包装器也适用于指针类型。

    class_&lt;GameObject, GameObject*&gt;("GameObject") ...

    【讨论】:

      【解决方案2】:

      无法评论@jkp,但他的提示对我有用。我的简约案例:

      RenderWorld.h

      class RenderWorld {
          public:
              ...
              void addEntity(RenderEntity* entity) {entities.push_back(entity);};
              std::vector<RenderEntity*> getEntities(void) {return entities;};
          private:
              std::vector<RenderEntity*> entities;
       };
      

      RenderEntity.h

       class RenderEntity {
           public:
               int getID(void) {return 42;};
       };
      

      python-exportage.py.h(编译成exported.pyd)

      BOOST_PYTHON_MODULE(exported)
      {
          class_<RenderWorld>("RenderWorld")
              .def("addEntity", &RenderWorld::addEntity)
              .def("getEntities", &RenderWorld::getEntities)
          ;
      
          class_<RenderEntity, RenderEntity*>("RenderEntity")
              .def("getID", &RenderEntity::getID)
          ;
      
          class_<std::vector<RenderEntity*> >("PyVec")
               .def(boost::python::vector_indexing_suite<std::vector<RenderEntity*> >())
          ;
      }
      

      我的 Python 会话:

      >>> import exported
      >>> world = exported.RenderWorld()
      >>> world
      <exported.RenderWorld object at 0x00000000024A0E58>
      >>> e1 = exported.RenderEntity()
      >>> e1
      <exported.RenderEntity object at 0x000000000284DF48>
      >>> e1.getID()
      42
      >>> world.addEntity(e1)
      >>> world.getEntities()
      <exported.PyVec object at 0x000000000234B1B0>  
      >>> world.getEntities()[0]
      <exported.RenderEntity object at 0x0000000002441F50>
      >>> world.getEntities()[0].getID()
      42
      >>> e1 == world.getEntities()[0]
      False
      

      注意:RenderEntity* 将被包装在另一个对象中。查看这些地址和最后的检查。从 c++ 的角度来看这是合乎逻辑的,但在 python 领域中则不然。

      【讨论】:

        【解决方案3】:

        您还必须包装您的 GameObject 类。在您拥有成员对象的 Python 包装器之前,它不会起作用。如果你不想暴露类的成员,你可以省略它们,只需要一个不透明的对象。

        此外,boost::python 非常适合共享指针。这为您提供了安全内存处理的额外好处。有没有机会将std::vector&lt;GameObject*&gt; 更改为std::vector&lt;boost::shared_ptr&lt;GameObject&gt; &gt;?这样会更好。

        【讨论】:

        • 感谢您的回答,是的,我已经用 boost.python 暴露了 GameObject。它仍然不适用于矢量。我现在无法实现 shared_ptr。您对如何导出矢量类有其他建议吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-12
        • 2021-05-14
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        相关资源
        最近更新 更多