c++ - 将派生类型的对象从 python 传递到期望 shared_ptr 为基类型的 C++ 函数时,Boost Python 运行时错误

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

我有一个接受 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/

相关文章:

c++ - 无法更改函数中的值

ruby-on-rails - 过滤器出现之前的顺序是什么?

javascript - 为什么 Object#create 必须先于子类的实例化

c++ - 作为类成员的通用 shared_ptr

c++ - 替换 shared_ptr<T> 中对对象的所有引用

c++ - 在 Visual C++ 6.0 MFC 中,是否可以将 CString 安全地视为简单类型而不是类?

c++ - 从类型 ‘foo*&’ 的右值初始化类型 ‘foo*’ 的非常量引用无效?

python - SWIG+c+Python : Passing and receiving c arrays

vb.net - "Overloads"在子类中如何工作?

c++ - 在 (unordered_)set 中修改 shared_ptr 是否安全?