2013-05-31 33 views
1

我有一个函数,它接受一个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>的功能?

回答

2

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

  • 使用boost::shared_ptr。 Boost.Python有代码来处理boost::shared_ptr之间的隐式转换,因为它们的element_type是分层的。
  • 经由boost::python::implicitly_convertible注册从std::shared_ptr<Derived>std::shared_ptr<AbstractBase>到的隐式转换。 std::shared_ptr满足了implicitly_convertible观的要求,所以只需要在模块定义注册转换:

    implicitly_convertible<std::shared_ptr<Derived>,   // Source 
             std::shared_ptr<AbstractBase> >(); // Target 
    
+0

好,这是一个有点沮丧!我以为,任何工作了'的boost :: shared_ptr'会为一个'的std :: shared_ptr'工作,但我想这仅仅是那些边缘的情况下我们要去都要处理,直到一切是一个很好的全部和入驻C++ 11 –