我有一个接受 std::shared_ptr 的函数,我想将派生类型的对象从 python 传递给该函数。这是我的类定义:
struct AbstractBase {
virtual void foo() = 0;
};
struct Derived : public AbstractBase {
virtual void foo(){
std::cout<<"Derived's foo!"<<std::endl;
}
};
struct Unrelated {
void bar(std::shared_ptr<AbstractBase> base_shared_ptr) {
base_shared_ptr->foo();
}
};
#endif /* CLASSES_H */
一个简单的纯 C++ 示例可以满足我的要求:
int main()
{
std::shared_ptr<Derived> d(new Derived);
Unrelated u;
u.bar(d);
}
输出:Derived's foo!
这是我的 Boost.Python 包装器代码:
#include <boost/python.hpp>
#include "classes.h"
BOOST_PYTHON_MODULE(shared_ptr_test) {
using namespace boost::python;
class_<AbstractBase,std::shared_ptr<AbstractBase>,boost::noncopyable>("AbstractBase",no_init);
class_<Derived,std::shared_ptr<Derived>,bases<AbstractBase>,boost::noncopyable>("Derived");
class_<Unrelated,std::shared_ptr<Unrelated>,boost::noncopyable>("Unrelated")
.def("bar",&Unrelated::bar);
}
这是我的简单 python 测试:
import shared_ptr_test
d=shared_ptr_test.Derived()
u=shared_ptr_test.Unrelated()
u.bar(d)
令我沮丧的是,这不起作用。它编译得很好,但是当我运行 python 脚本时,我得到这个错误:
Traceback (most recent call last):
File "test.py", line 5, in <module>
u.bar(d)
Boost.Python.ArgumentError: Python argument types in
Unrelated.bar(Unrelated, Derived)
did not match C++ signature:
bar(Unrelated {lvalue}, std::shared_ptr<AbstractBase>)
改变 bar
采取shared_ptr<Derived>
修复了这个,所以我知道内部 Boost.Python 正在使用 shared_ptr
管理对象秒。我还需要做些什么来让 Boost.Python 意识到可以传递 shared_ptr<Derived>
吗?到一个期待 shared_ptr<Base>
的函数?
最佳答案
Boost.Python 需要知道指向 Derived
的智能指针可以转换为指向 AbstractBase
的智能指针.这可以通过以下任一方式完成:
- 使用
boost::shared_ptr
. Boost.Python 有代码来处理boost::shared_ptr
之间的隐式转换。这是他们的element_type
是分层的。 从
std::shared_ptr<Derived>
注册一个隐式转换至std::shared_ptr<AbstractBase>
通过boost::python::implicitly_convertible
.std::shared_ptr
满足implicitly_convertible
的概念要求, 所以它只需要在模块定义中注册转换:implicitly_convertible<std::shared_ptr<Derived>, // Source std::shared_ptr<AbstractBase> >(); // Target
关于c++ - 将派生类型的对象从 python 传递到期望 shared_ptr 为基类型的 C++ 函数时,Boost Python 运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16853477/