2012-01-12 2 views
2

나는 std :: list를 매개 변수로 반환하는 Python의 C++ 메소드를 호출하려고합니다. 내가 파이썬에서 함수를 호출 할 때SWIG C++ to Python : std :: list를 파이썬의 인자로 반환하기

%typemap(in) (std::list<Service*> &) (std::list<Service*> temp) { 
    $1 = &temp; 
} 

%typemap(argout) (std::list<Service*>&) { 
    Py_XDECREF($result); /* Blow away any previous result */ 
    $result = PyList_New((*$1).size()); 
    qList<Service*>::iterator it = (*$1).begin(); 
    int i = 0; 
    while(it != (*$1).end()) { 
     PyList_SetItem($result,i,SWIG_NewPointerObj((void*)(*it), SWIGTYPE_p_Service, 0)); 
     it++; i++; 
    } 
} 

, 나는 C++ 코드에서 중단 할 수 있습니다 : 여기

void FindAllServices(int id, std::list<Service*> &services) 

는 표준 : : 목록 내 타입 맵입니다 : 여기

는 C++ 프로토 타입입니다 모든 것이 괜찮은지 확인하십시오 (즉, 일부 서비스 포인터가 목록에 복사 됨). 그러나 파이썬에서 얻은 목록은 비어 있습니다.

내가 뭘 잘못하고 있는지 알겠습니까?

감사합니다.

+0

Swig에는 일부 STL 클래스에 대한 미리 정의 된 typemaps가 있습니다. SWIG의'Lib/Python' 디렉토리를 보라. –

답변

0

귀하의 argout 코드는 새로운 목록을 만듭니다. 원래 목록에 대한 참조를 가져 와서 대신 수정해야합니다. 나는 양을 모릅니다. 그래서 어떻게해야할지 모르겠습니다.

파이썬 인터페이스의 경우 일반적으로 전달 된 목록을 수정하는 대신 새 목록이 반환되도록 포장합니다. 그 C + + 관용구,하지만 정말 파이썬 하나.

+0

$ result가 argout 매개 변수를 대체해야한다고 생각했습니다. 어쨌든 나는 C++로 대신 할 수있는 방법을 찾는다. 당신의 도움을 주셔서 감사합니다. –

0

여기에 제가 사용하고있는 코드가 있습니다. 그것은 아주 잘 작동합니다.

%typemap(out) std::list<AbnormalCondition> 
{ 
    PyObject* outList = PyList_New(0); 

    int error; 

    std::list<AbnormalCondition>::iterator it; 
    for (it=$1.begin() ; it != $1.end(); it++) 
    { 
     AbnormalCondition object = (*it); 

     PyObject* pyAbnormalCondition = SWIG_NewPointerObj((new AbnormalCondition(static_cast< const AbnormalCondition& >(object))), SWIGTYPE_p_AbnormalCondition, SWIG_POINTER_OWN | 0); 

     error = PyList_Append(outList, pyAbnormalCondition); 
     Py_DECREF(pyAbnormalCondition); 
     if (error) SWIG_fail;  
    } 

    $result = outList; 
} 

%typemap(in) std::list<AbnormalCondition> 
{ 
    //$input is the PyObject 
    //$1 is the parameter 

    if (PyList_Check($input)) 
    { 
     std::list<AbnormalCondition> listTemp; 

     for(int i = 0; i<PyList_Size($input); i++) 
     { 
      PyObject* pyListItem = PyList_GetItem($input, i); 

      AbnormalCondition* arg2 = (AbnormalCondition *) 0 ; 

      int res1 = 0; 
      void *argp1; 

      res1 = SWIG_ConvertPtr(pyListItem, &argp1, SWIGTYPE_p_AbnormalCondition, 0 | 0); 
      if (!SWIG_IsOK(res1)) 
      { 
       PyErr_SetString(PyExc_TypeError,"List must only contain AbnormalCondition objects"); 
       return NULL; 
      } 
      if (!argp1) 
      { 
       PyErr_SetString(PyExc_TypeError,"Invalid null reference for object AbnormalCondition"); 
       return NULL; 
      } 

      arg2 = reinterpret_cast< AbnormalCondition * >(argp1); 
      listTemp.push_back(*arg2); 
     } 

     $1 = listTemp; 
    } 
    else 
    { 
     PyErr_SetString(PyExc_TypeError,"Wrong argument type, list expected"); 
     return NULL; 
    } 
}