SWIG与python和C:参数

时间:2014-04-11 14:47:54

标签: python c swig

我有这个功能:

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”参数的值?

2 个答案:

答案 0 :(得分:1)

您可以使用多参数类型图。

%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)初始化为大小,a($ 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]]

答案 1 :(得分:0)

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

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

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