SWIG C-to-Python Int Array

Ada*_*dam 11 c python linux swig

我试图使用swig从python中使用以下原型访问C函数:

int cosetCoding(int writtenDataIn, int newData, const int memoryCells, int *cellFailure, int failedCell);
Run Code Online (Sandbox Code Playgroud)

Swig创建.so没有问题,我可以将它导入到python中,但是当我尝试使用以下内容访问它时:

 cosetCoding.cosetCoding(10,11,8,[0,0,0,0,0,0,0,0],0)
Run Code Online (Sandbox Code Playgroud)

我得到以下回溯:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: in method 'cosetCoding', argument 4 of type 'int *'
Run Code Online (Sandbox Code Playgroud)

指针应该是一个int数组,其大小由memoryCells定义

Mar*_*nen 14

如果可以,请使用ctypes.它更简单.但是,既然你要求SWIG,你需要的是一个描述如何处理int*的类型映射.SWIG不知道可以指出多少个整数.以下是关于多参数类型地图的SWIG文档中的示例:

%typemap(in) (const int memoryCells, int *cellFailure) {
  int i;
  if (!PyList_Check($input)) {
    PyErr_SetString(PyExc_ValueError, "Expecting a list");
    return NULL;
  }
  $1 = PyList_Size($input);
  $2 = (int *) malloc(($1)*sizeof(int));
  for (i = 0; i < $1; i++) {
    PyObject *s = PyList_GetItem($input,i);
    if (!PyInt_Check(s)) {
        free($2);
        PyErr_SetString(PyExc_ValueError, "List items must be integers");
        return NULL;
    }
    $2[i] = PyInt_AsLong(s);
  }
}

%typemap(freearg) (const int memoryCells, int *cellFailure) {
   if ($2) free($2);
}
Run Code Online (Sandbox Code Playgroud)

请注意,使用此定义时,从Python调用时会省略memoryCells参数并只传递一个数组,例如[1,2,3,4]for cellFailure.typemap将生成memoryCells参数.

PS我可以发布一个完整的工作示例(对于Windows),如果你想要它.


kyn*_*nan 8

马克是对的,你需要一个打字机.但是,如果您使用numpy.i(http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html),则无需手动编写类型图,这已经定义了将C转换为必要的类型映射NumPy数组,反之亦然.

在你的情况下(假设cellFailure是一个输入数组)你将要使用

%apply (int DIM1, int* IN_ARRAY1) {(int memoryCells, int *cellFailure)}
Run Code Online (Sandbox Code Playgroud)

注意(正如Mark已经指出的那样)这样可以方便地将C中的这2个参数融合到单个python数组参数中,无需单独传递数组长度.您的电话将如下所示:

from numpy import asarray
cosetCoding.cosetCoding(10,11,asarray([0,0,0,0,0,0,0,0]),0)
Run Code Online (Sandbox Code Playgroud)