我工作的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
;
但这没有用 - 任何建议?