1

我有一个接受 std::shared_ptr 的函数,我想从 python 将 Derived 类型的对象传递给这个函数。这是我的类定义:

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>)

更改barshared_ptr<Derived>修复此问题,因此我知道内部 Boost.Python 正在使用shared_ptrs 管理对象。我还需要做些什么来让 Boost.Python 意识到可以将 a 传递shared_ptr<Derived>给期望 a 的函数shared_ptr<Base>吗?

4

1 回答 1

2

Boost.Python 需要知道一个智能指针Derived可以转换为一个智能指针AbstractBase。这可以通过以下任一方式完成:

  • 使用boost::shared_ptr. boost::shared_ptr当 selement_type是分层的时,Boost.Python 有代码来处理 s 之间的隐式转换。
  • 注册从std::shared_ptr<Derived>std::shared_ptr<AbstractBase>via的隐式转换boost::python::implicitly_convertiblestd::shared_ptr符合 的概念要求implicitly_convertible,因此只需要在模块定义中注册转换即可:

    implicitly_convertible<std::shared_ptr<Derived>,          // Source
                           std::shared_ptr<AbstractBase> >(); // Target
    
于 2013-05-31T14:28:31.633 回答