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。