std :: shared_ptr用于使用boost :: python从C ++抽象类派生的具体Python类

时间:2015-11-09 19:50:19

标签: c++ shared-ptr boost-python

我工作的C ++库中的重要功能依赖于std::shared_ptr。例如,要将组件添加到 Actor ,我会调用带有原型的函数

Actor::add_component(std::shared_ptr<Component> cmp);

std::shared_ptr<Component>存储在内部地图中。在C ++级别,应用程序运行良好。

在尝试依赖boost::python创建Python绑定时,我遇到了在Python中创建自定义组件的问题,因为这些类是从C ++ Component抽象基类派生的。

这是一个最小但完整的例子:

// C++ library and Python bindings
#include <boost/python.hpp>
#include <memory>

class Base {
 public:
  virtual ~Base() = default;
  void behavior() const {
    return this->custom_behavior();
  }
 private:
  virtual void custom_behavior() const = 0;
};

class BaseWrapper
    : public Base,
      public boost::python::wrapper<Base> {
 private:
  void custom_behavior() const override {
    this->get_override("custom_behavior")();
  }
};

void foo(const Base& item) {
  item.behavior();
}

void bar(const Base* const item) {
  item->behavior();
}

void baz(const std::shared_ptr<Base>& item) {
  item->behavior();
}

BOOST_PYTHON_MODULE(library) {
  using namespace boost::python;

  class_<BaseWrapper,
         std::shared_ptr<BaseWrapper>,
         boost::noncopyable>("Base")
      .def("behavior", &BaseWrapper::behavior)
      ;

  def("foo", &foo);
  def("bar", &bar);
  def("baz", &baz);
}

我希望创建自定义组件,如下所示:

import library

class Derived(library.Base):
    def custom_behavior(self):
        print "Derived::custom_behavior()"


def main():

    # Instance of a Python class derived from a C++ class.
    derived = Derived()

    print "direct call to Derived.behavior..."
    derived.behavior()

    print "call foo(const Base& item)"
    library.foo(derived)

    print "call bar(const Base* const item)"
    library.bar(derived)

    print "call baz(const std::shared_ptr<Base>& item)"
    library.baz(derived)


if __name__ == "__main__":
    main()

但是,正如预期的那样,对baz的调用失败了:

$ python test-library.py
direct call to Derived.behavior...
Derived::custom_behavior()
call foo(const Base& item)
Derived::custom_behavior()
call bar(const Base* const item)
Derived::custom_behavior()
call baz(const std::shared_ptr<Base>& item)
Traceback (most recent call last):
  File "test-library.py", line 27, in <module>
    main()
  File "test-library.py", line 23, in main
    library.baz(derived)
Boost.Python.ArgumentError: Python argument types in
    library.baz(Derived)
did not match C++ signature:
    baz(std::shared_ptr<Base>)

我试图覆盖派生自library.Base的所有Python类的构造函数,期望&#34;启动现有&#34;作为std::shared_ptr<BaseWrapper>

std::shared_ptr<BaseWrapper> constructor() {
    return std::make_shared<BaseWrapper>();
}

class_<BaseWrapper, std::shared_ptr<BaseWrapper>, noncopyable>
    ("Base", no_init")
    .def("__init__", make_constructor(constructor))
    // ... other methods
    ;

但这没有用 - 任何建议

0 个答案:

没有答案