SWIG C++ 到 Python: 返回 std::list 作为参数到 Python
我正在尝试从Python中调用一个C++的方法,这个方法会把一个std::list作为参数返回。
这是C++的原型:
void FindAllServices(int id, std::list<Service*> &services)
这是我为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++;
}
}
当我从Python调用这个函数时,我可以进入C++的代码,看到一切正常(也就是说,一些Service指针被复制到了列表中)。但是,我在Python中得到的列表是空的。
你知道我可能哪里做错了吗?
谢谢!
2 个回答
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;
}
}
0
你的代码创建了一个新的列表。你需要获取原始列表的引用,然后修改那个列表。我对swig不太了解,所以不知道怎么做。
对于Python接口,我通常会把它包装一下,让它返回一个新的列表,而不是修改传入的列表。这是C++的写法,但在Python中并不常见。