2013-05-31 1 views
1

std :: shared_ptr을 사용하는 함수가 있는데이 함수에 Derived 유형의 객체를 전달하려고합니다. 파이썬. 여기 내 클래스 정의는 다음과 같습니다Python에서 파생 된 유형의 객체를 C++ 함수로 전달할 때 Boost Python 런타임 오류가 발생했습니다. shared_ptr이 기본 유형이 될 것으로 기대합니다.

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

출력 :

#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); 
} 
: Derived's foo! 여기

내 Boost.Python 래퍼 코드

다음은 간단한 파이썬 테스트입니다.

import shared_ptr_test 

d=shared_ptr_test.Derived() 
u=shared_ptr_test.Unrelated() 
u.bar(d) 

실망 스럽지만 작동하지 않습니다. 그것은 잘 컴파일,하지만 난 파이썬 스크립트를 실행할 때이 오류가 얻을 :

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

shared_ptr<Derived> 수정이 걸릴 bar 변경을, 그래서 내부적으로 Boost.Python이 shared_ptr의와 개체를 관리하는 것을 알고있다. Boost.Python에 을 기대하는 함수에 shared_ptr<Derived>을 전달하는 것이 좋다는 것을 깨닫게하려면 더 많은 것을해야합니까?

답변

2

Boost.Python은 Derived에 대한 스마트 포인터를 AbstractBase에 대한 스마트 포인터로 변환 할 수 있다는 점을 알아야합니다. 이는 다음 중 하나를 사용하여 수행 할 수 있습니다.

  • boost::shared_ptr을 사용하십시오. Boost.Python에는 element_type이 계층적일 때 boost::shared_ptr 사이의 암시 적 변환을 처리하는 코드가 있습니다.
  • std::shared_ptr<Derived>에서 std::shared_ptr<AbstractBase>까지 boost::python::implicitly_convertible을 통한 암시 적 변환을 등록하십시오. std::shared_ptrimplicitly_convertible에 대한 개념의 요구 사항을 충족, 그래서 그것은 단지 모듈 정의에 전환 등록이 필요합니다

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

, 그건 좀 실망이야! 나는'boost :: shared_ptr'에 대해 작동하는 것이'std :: shared_ptr'에 대해 작동한다고 가정 했었습니다. 그러나 이것은 모든 것이 모두 훌륭 할 때까지 처리해야 할 엣지 케이스 중 하나라고 생각합니다. C++ 11에 정착했다. –