SWIG与python和C:参数

我有这个function:

void func(int* a, int b); 

我希望在python中提供这样的内容:

 func(list, int) 

即,用户传递一个列表和一个整数(告诉函数应该在列表中存储多少条目)。 为此,我需要在“a”的初始化中知道“b”的值(因为我需要临时的原始C int数组)。

 %typemap(in) ( int* a) { //need to allocate sizeof(int) * b bytes temporarily } 

但我不知道“b”的值,因为它只是稍后解析!

如何访问“b”参数的值?

您可以使用多参数类型映射。

 %typemap(in) (const int *a, int b) %{ $2 = (int)PyList_Size($input); $1 = new int[$2]; for(Py_ssize_t i = 0; i < $2; ++i) $1[i] = PyLong_AsLong(PyList_GET_ITEM($input,i)); %} %typemap(freearg) (const int* a, int b) %{ delete [] $1; %} 

这假设您传入一个列表(因此const int* )。 由于Python列表知道它的大小,因此也不需要传递大小。 另请注意,上面的示例中没有错误检查。

通过这个,您可以为这两个参数传递一个Python对象($ input)。 b ($ 2)用大小初始化,($ 1)分配一个大小的新int数组。 数组的元素将复制到此数组。

freearg typemap在调用函数后提供清理。

你这样使用它:

 func([1,2,3,4,5]) 

如果要返回列表,可以使用以下内容:

 %typemap(in) (int *a, int b) %{ $2 = (int)PyLong_AsLong($input); $1 = new int[$2]; %} %typemap(argout) (int *a, int b) (PyObject* tmp) %{ tmp = PyList_New($2); for(Py_ssize_t i = 0; i < $2; ++i) PyList_SET_ITEM(tmp, i, PyLong_FromLong($1[i])); $result = SWIG_Python_AppendOutput($result, tmp); %} %typemap(freearg) (int* a, int b) %{ delete [] $1; %} 

注意非const int *a 。 Python不需要列表作为输入参数来返回一个,因此输入类型映射只需要一个整数(为简洁起见,删除了错误检查)。 argout typemap从返回值构建Python列表,并将它们附加到输出结果。

像这样用它:

 func(5) # returns for example [1,2,3,4,5] 

如果func有返回值,它将返回[retval, [1,2,3,4,5]]

我以为我看到你可以使用%apply来复制typemap-for-array-and-length typemap,以便SWIG将它用于你的函数参数。 类似的东西(现在无法检查确切的语法):

 %apply (int *ARRAY, int LENGTH) { (int* a, int b) }; void func(int* a, int b); 

另外,看看将Python列表转换为char ** :您可以通过将所有“char *”替换为“int”来使其适应int。