2012-09-06 6 views
1

를 통해 노출 확장. 지금 난 단지 클래스 자체와 GetName() 메소드를 노출하고은 가상 C++ 클래스는 내가 Boost.Python를 사용하여이 C++ 클래스를 노출하는 것을 시도하고있다 Boost.Python

class VAlgorithm_callback: public VAlgorithm { 
public: 
    VAlgorithm_callback(PyObject *p, const char *name) : 
     self(p), VAlgorithm(name) { 
    } 
    const char * GetName() const { 
    return call_method<const char *>(self, "GetName"); 
    } 

    static const char * GetName_default(const VAlgorithm& self_) { 
    return self_.VAlgorithm::GetName(); 
    } 

private: 
    PyObject *self; 
}; 

: this example에 따라, 나는 콜백 클래스를 정의했다. 이 가상 클래스이기 때문에, 나는 BOOST_PYTHON_MODULE 내부에이 코드를 배치 :

class_<VAlgorithm, VAlgorithm_callback, boost::noncopyable>("VAlgorithm", no_init) // 
    .def("GetName", &VAlgorithm_callback::GetName_default); // 

나는이를 컴파일하고 파이썬 쉘에서 모듈을로드 할 수 있습니다. 그럼 난 C++ 코드에 정의 된 GetName() 디폴트의 구현 하위 클래스를 정의하고 호출 할 :

>>> class ConcAlg1(VAlgorithm): 
... pass 
... 
>>> c1 = ConcAlg1("c1") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
RuntimeError: This class cannot be instantiated from Python 
>>> class ConcAlg2(VAlgorithm): 
... def __init__(self, name): 
...  pass 
... 
>>> c2 = ConcAlg2("c2") 
>>> c2.GetName() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
Boost.Python.ArgumentError: Python argument types in 
    VAlgorithm.GetName(ConcAlg2) 
did not match C++ signature: 
    GetName(VAlgorithm) 
>>> class ConcAlg3(VAlgorithm): 
... def __init__(self, name): 
...  super(ConcAlg3, self).__init__(self, name) 
... 
>>> c3 = ConcAlg3("c3") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in __init__ 
RuntimeError: This class cannot be instantiated from Python 

내가 (단지 처음으로 이러한 문제에 직면) 전문가가 아니다, 그러나 그것은 나에게 보인다 ConcAlg1과 ConcAlg3은 VAlgorithm 객체를 인스턴스화하려고 시도하고 VAlgorithm을 노출 할 때 사용되는 no_init 매개 변수 때문에 실패합니다 (생략 할 수 없거나 코드가 컴파일되지 않습니다). ConcAlg2는 GetName()을 호출 할 수 없습니다. VAlgorithm의 자식으로 인식되지 않습니다. 나는 사소한 일을해야만한다. 그러나 나는 (나는 Boost.Python과 확장 기능의 초보자이다.) 무엇을 알아낼 수 없다. 아무도 나를 도울 수 있습니까? 감사합니다

답변

0

나는 이와 비슷한 작업을 수행했습니다. 당신이 당신의 코멘트에서 이미 발견 한 것을 따라 다니는 것이 어떻습니까?

파이썬에서 VAlgorithm에서 파생되는 클래스의 인스턴스를 만들 때 VAlgorithm_callback은이를 나타 내기 위해 C++에서 인스턴스화되어야합니다. BOOST_PYTHON_MODULE에 생성자를 선언하지 않으면 불가능합니다. 그 확인을해야 예제에서 수행 방법 수행

: 당신이 하위 클래스의 초기화를 정의 할 때, 당신은 부모 생성자를 호출하려면 다음 구문을 사용할 수 있습니다

class_<VAlgorithm, VAlgorithm_callback, boost::noncopyable>("VAlgorithm", init<std::string>()) 

을 (하지만 코드가 수도 너무 일해, 그게 내가하는 것처럼). 사용 된 예에서는 을 정의하지 않으므로 대신 상위 하나가 호출됩니다.

class ConcAlg3(VAlgorithm): 
    def __init__(self, name): 
    VAlgorithm.__init__(self, name) 
+0

사실, 오류를 찾은 후 내 대답을 썼습니다. 부실한 문서화 된 예제와 Boost에 대한 나의 가난한 지식으로 인해 오도 된 것 같습니다. 파이썬. 당신의 도움을 주셔서 감사합니다! –

0

나는 해결책을 찾았다 고 생각합니다. 내 질문에 인용 한 예제와 부스트 문서 here을 살펴보면서, 문제는 콜백 클래스가 Boost.Python에 의해 래핑 된 실제 클래스이고 구체적인 클래스 여야한다는 것입니다. 그래서 나는 그것에서 누락 된 순수 가상 메서드 구현 :

class VAlgorithm_callback: public VAlgorithm { 
public: 
    VAlgorithm_callback(PyObject *p, const char *name) : 
     self(p), VAlgorithm(name) { 
    } 

    virtual bool Initialize() { 
    return call_method<bool>(self, "Initialize"); 
    } 
    virtual bool Process() { 
    return call_method<bool>(self, "Process"); 
    } 
    virtual bool Finalize() { 
    return call_method<bool>(self, "Finalize"); 
    } 

    const char * GetName() const { 
    return call_method<const char *>(self, "GetName"); 
    } 

// Supplies the default implementation of GetName 
    static const char * GetName_default(const VAlgorithm& self_) { 
    return self_.VAlgorithm::GetName(); 
    } 

private: 
    PyObject *self; 
}; 

을하고 또한 같은 래퍼 수정 : 나는 파이썬에서 자식 클래스를 정의하고 GetName() 메소드의 기본을 호출 할 수 있습니다 지금

class_<VAlgorithm, boost::shared_ptr<VAlgorithm_callback>, boost::noncopyable ("VAlgorithm", init<const char *>()) // 
.def("Initialize", &VAlgorithm_callback::Initialize) 
.def("Process", &VAlgorithm_callback::Process) 
.def("Finalize", &VAlgorithm_callback::Finalize) 
.def("GetName", &VAlgorithm_callback::GetName_default); 

를 :

>>> class ConcAlg(VAlgorithm): 
... pass 
... 
>>> c = ConcAlg("c") 
>>> c.GetName() 
'c' 
>>>