2017-09-20 3 views
1

Boost.Python을 통해 내 C++ 클래스를 노출합니다. 내 의도는 내부 참조가있는 사용자 정의 클래스 유형의 멤버 변수를 노출하는 것입니다. boost :: type의 멤버 변수를 도입하기로 결정하기 전까지는 잘 작동했습니다. optional <T>.Exposing boost :: optional <T> Boost.Python을 통해 내부 참조 또는 없음

부스트를 노출하는 방법을 보여주는 몇 가지 훌륭한 게시물이 있습니다. 선택 사항 : <T>. 특히 this converter을 구현했습니다. 내 코드의 기타 관련 부분은 다음과 같이 :

struct Bar {} 

struct Foo { 
    boost::optional<Bar> bar; 
} 

BOOST_PYTHON_MODULE(mymodule) { 
    using namespace boost::python; 

    python_optional<Bar>(); //registering the converter 

    class_<Foo>("Foo") 
    .add_property ("bar", make_getter(&Foo::bar, return_value_policy<return_by_value>()), make_setter(&Foo::bar)) 
    ; 
} 

내가 return_value_policy<reference_existing_object>() 또는 return_internal_reference<>() 중 하나와 return_value_policy<return_by_value>()를 교체했습니다.

>> import mymodule 
>> foo = mymodule.Foo() 
>> bar = foo.bar 
TypeError: No Python class registered for C++ class boost::optional<Bar> 

나의 이해는 내가 지금은 부스트 ​​:: <T> 객체 선택에 대한 참조를 얻고 있다는 것입니다 : 둘 다 파이썬 형식 오류를 생산했다. 그러나 등록 된 변환기는 boost :: optional <T> 개체이며 해당 개체에 대한 참조가 아니기 때문에 호출되지 않습니다. 나는 변환기를 바꾸는 것에 대하여 생각했다. 그러나 나는 이것에 초보적이다. 그리고 나는 방법을 정말로 모른다. 어떤 제안?

답변

0

struct Foo에 getter를 추가하여 해결 방법을 찾았습니다.이 메서드는 boost :: optional에 의해 보유 된 객체에 대한 포인터를 반환하거나 boost :: none의 경우에는 nullptr을 반환합니다. &*barconst Bar*을 반환하므로 const_cast을 사용해야했습니다.

>> import mymodule 
>> foo = mymodule.Foo() 
>> foo.bar = mymodule.Bar() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
Boost.Python.ArgumentError: Python argument tpyes in 
    None.None(Foo, Bar) 
did not match C++ signature: 
    None(FooBase {lvalue}, boost::optional<Bar>) 

클래스 Foobar에 대한 게터와 세터를 정의하는 문제를 해결하려면 다음의 경우 bar에서

struct Bar {} 

struct Foo { 
    Bar* getBar() { return (bar ? const_cast<Bar*>(&*bar) : nullptr); }; 
    boost::optional<Bar> bar; 
} 

BOOST_PYTHON_MODULE(mymodule) { 
    using namespace boost::python; 

    python_optional<Bar>(); //registering the converter 

    class_<Foo>("Foo") 
    .add_property ("bar", make_function(static_cast< Bar*(Foo::*)() >(&Foo::getBar), return_internal_reference<>()), make_setter(&Foo::bar)) 
    ; 
} 

과 같이하면 ArgumentError가 발생합니다 Foo 파이썬의 기본 클래스에 속하는 .

struct Bar {} 

struct FooBase { 
    boost::optional<Bar> bar; 
} 

struct Foo : public FooBase { 
    Bar* getBar() { return (bar ? const_cast<Bar*>(&*bar) : nullptr); }; 
    void setBar(const Bar* bar) { bar ? this->bar = *bar : this->bar = boost::none; } 
} 

void (Foo::*foo_bar_set)(const Bar*) = &Foo::setBar; 

BOOST_PYTHON_MODULE(mymodule) { 
    using namespace boost::python; 

    python_optional<Bar>(); //registering the converter 

    class_<Foo>("Foo") 
    .add_property ("bar", make_function(static_cast< Bar*(Foo::*)() >(&Foo::getBar), return_internal_reference<>()), foo_bar_set) 
    ; 
} 
관련 문제