2015-02-04 2 views
1

저는 swig로 감싸이고 파이썬에서 사용하는 C++ 코드를 가지고 있습니다. C++ 코드 안에 콜백 파이썬 코드를 실행하는 방법을 만들고 싶습니다. 그래서 "추상"클래스를 만들었습니다. (아직 추상화되지 않았습니다.) 그리고 .i 파일 내부에서 C++로 서브 라이징하고 있습니다. 여기 swig를 사용하여 상속 C++에서 오류가 발생했습니다.

%feature("director") PyListener; 
using namespace std; 
%{ 
#include "../core/listener.h" 
%} 

%include "../core/listener.h" 

class PyListener : public Listener { 
    PyObject * function; 
public: 
    PyListener() {}; 
    PyListener(PyObject * func) : function(func) {}; 
    void register_new() {Py_XINCREF(function);}; 
    ~PyListener() {Py_XDECREF(function);}; 
    void run(Msg &m) { 
     PyGILState_STATE gstate; 
     gstate = PyGILState_Ensure(); 
     PyObject *pValue = PyCObject_FromVoidPtr((void*)&m,NULL); 
     PyObject *pArgs = PyTuple_New(1); 
     PyTuple_SetItem(pArgs, 0, pValue); 
     PyObject_CallObject(function, pArgs); 
     PyGILState_Release(gstate); 
    }; 
}; 

하지만 컴파일하는 동안

는 당신 때문에

/bin/sh ../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../.. -I. -I./../core -I./../../../include -I/opt/regression/usr/include/ -I./../../include_dep/ -I/usr/include/python2.6 -fPIC -g -O2 -MT sim_wrap.lo -MD -MP -MF .deps/sim_wrap.Tpo -c -o sim_wrap.lo sim_wrap.cxx 
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../.. -I. -I./../core -I./../../../include -I/opt/regression/usr/include/ -I./../../include_dep/ -I/usr/include/python2.6 -fPIC -g -O2 -MT sim_wrap.lo -MD -MP -MF .deps/sim_wrap.Tpo -c sim_wrap.cxx -fPIC -DPIC -o .libs/sim_wrap.o 
sim_wrap.cxx: In function ‘PyObject* _wrap_new_PyListener__SWIG_0(PyObject*, PyObject*)’: 
sim_wrap.cxx:36391: error: ‘PyListener’ was not declared in this scope 
sim_wrap.cxx:36391: error: ‘result’ was not declared in this scope 
sim_wrap.cxx:36394: error: expected primary-expression before ‘)’ token 
sim_wrap.cxx:36394: error: expected ‘;’ before ‘new’ 
... 
+0

이 시스템에'python-dev' /'python-devel' 패키지가 설치되어 있습니까? –

+0

물론이 리스너 부분을 제거하면 다른 swig 함수를 컴파일하고 사용할 수 있습니다. –

답변

0

를 얻을 내가

.H 파일

class Listener { 
public: 
    Listener(); 
    virtual void register_new(); 
    virtual void run(Msg &m); 
    virtual ~Listener(); 
}; 

.I 파일을 쓴 일부 코드입니다 둘 다 선언하고있다. SWIG 인터페이스 내에 %inline 안에 동봉해야하는 동시에 새 클래스를 정의해야합니다.

%inline %{ 
    class PyListener : public Listener { 
     PyObject * function; 
    public: 
     PyListener() {}; 
     PyListener(PyObject * func) : function(func) {}; 
     void register_new() {Py_XINCREF(function);}; 
     ~PyListener() {Py_XDECREF(function);}; 
     void run(Msg &m) { 
      PyGILState_STATE gstate; 
      gstate = PyGILState_Ensure(); 
      PyObject *pValue = PyCObject_FromVoidPtr((void*)&m,NULL); 
      PyObject *pArgs = PyTuple_New(1); 
      PyTuple_SetItem(pArgs, 0, pValue); 
      PyObject_CallObject(function, pArgs); 
      PyGILState_Release(gstate); 
     }; 
    }; 
%} 

이렇게하면 SWIG가 형식을 랩핑 할뿐만 아니라 생성 된 C++ 코드에도 선언/정의를 전달합니다. PyListener은 SWIG 인터페이스에만 해당하므로 다른 헤더 파일에서는 알 수 없기 때문에 이러한 작업이 필요합니다.

+0

감사합니다! 또 다른 작은 질문이 있습니다 –

+0

감사합니다! 내 파이썬 코드에서 를 도울 수 내가 다른 작은 질문이있다 나는이 흐르는 수행 이 py_sim = bms.PyListener (FUNC)를 ms_node.setCallBack (py_sim) 다음 그리고 난이 기능과 SWIG를 떠나 그 py_sim 더입니다 생각하지 않습니다 더 이상 사용하기 때문에 그는 그것을 삭제합니다 그리고 나서 C++ 코드가 충돌합니다 newobject와 함께 행운을 빕니다. –

+0

@rafiwiener 대신 모듈과 함수를 char *로 저장하는 편이 낫지 않습니까? 뭔가 :'cb = PyObject_GetAttrString (module, function); PyObject * result = PyObject_CallObject (cb, args); ' – sambha

관련 문제