2012-01-12 49 views
2

我想從Python返回一個std :: list作爲參數的C++中調用一個方法。SWIG C++到Python:返回一個std :: list作爲參數給Python

這裏是C++原型:

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

這裏是我的std ::列表類型映射:

%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++; 
    } 
} 

當我打電話從Python的功能,我可以在C++代碼破裂,看到一切正常(即一些服務指針被複制到列表中)。但是,我在Python中獲得的列表是空的。

你知道我可能會做錯什麼嗎?

謝謝!

+0

Swig爲某些STL類預定義了類型映射。請參閱SWIG的「Lib/Python」目錄。 – 2012-01-16 03:21:57

回答

0

您的argout代碼會創建一個新列表。您必須獲得對原始列表的引用並修改它。我不知道斯威格,所以我不知道該怎麼做。

對於一個python界面,我通常會包裝它,以便返回一個新列表,而不是修改傳入的列表。這是一個C++習慣用法,但不是真正的python。

+0

我認爲$結果應該取代argout參數。無論如何,我找到一種方法,而不是使用C++來完成。謝謝你的幫助。 – 2012-01-13 14:04:56

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