python的swig typemap:输入和输出数组

我有一个我想在Python中使用的C函数:

extern int convertAtoB( stateStruct *myStruct, const double PointA[3], double PointB[3]); 

使用SWIG,我想我需要定义一个类型映射来转换两个点(PointA是输入,PointB是输出),以便Python可以使用它。 在typemaps.i中似乎没有与此一起使用的类型映射,因此我必须定义一个。 我似乎无法在SWIG文档中找到数组的示例。

我想像这样使用这个库:

 s = externalStruct() point_a = [1, 2, 3] result, point_b = convertAtoB(s, point_a) print point_b "expect [4, 5, 6]" 

我该怎么办? 谢谢

你快到了。 要删除python签名中的伪参数,您需要将PointB[3] %typemap(in)更改为%typemap(in,numinputs=0)以指示SWIG忽略该输入值(您已经在反正它的副本)。 这将从python方法签名中删除伪参数。

但是,我不确定是否需要为该专业化复制整个%typemap(in) 。 可能有一种方法可以重用实际的类型映射,但我不知道如何。 否则你最终会得到额外的

 %typemap(in,numinputs=0) double PointB[3] (double temp[$1_dim0]) { int i; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } if (PySequence_Length($input) != $1_dim0) { PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); return NULL; } for (i = 0; i < $1_dim0; i++) { PyObject *o = PySequence_GetItem($input,i); if (PyNumber_Check(o)) { temp[i] = (double) PyFloat_AsDouble(o); } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); return NULL; } } $1 = temp; } 

这是我找到的一个解决方案,但它可能不是最好的:

 %typemap(in) double[ANY] (double temp[$1_dim0]) { int i; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } if (PySequence_Length($input) != $1_dim0) { PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); return NULL; } for (i = 0; i < $1_dim0; i++) { PyObject *o = PySequence_GetItem($input,i); if (PyNumber_Check(o)) { temp[i] = (double) PyFloat_AsDouble(o); } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); return NULL; } } $1 = temp; } 

这是我最终遇到的将Python列表转换为数组的文档中的一个示例。 下一部分更难,拼凑几个例子,我可以将返回数组转换为python列表:

 %typemap(argout) double PointB[3]{ PyObject *o = PyList_New(3); int i; for(i=0; i<3; i++) { PyList_SetItem(o, i, PyFloat_FromDouble($1[i])); } $result = o; } 

但是,我必须为API中的每个返回值创建其中一个。 此外,我必须使用虚拟值作为参数调用它:

 point_b = convertAtoB(s, point_a, dummy) 

有没有更好的办法?

这是一个老线程,但我回答它,因为没有那么多关于SWIG的post。

具体针对上述情况

 %typemap(in, numinputs=0) double PointB[3] { double tmp[3]; $1 = tmp; } %typemap(argout) double PointB[3] { PyObject *o = PyList_New(3); int i; for(i=0; i<3; i++) { PyList_SetItem(o, i, PyFloat_FromDouble($1[i])); } $result = o; }