Python 返回SWIG中未指定大小的numpy数组

Python 返回SWIG中未指定大小的numpy数组,python,c,numpy,swig,Python,C,Numpy,Swig,我的目标是将SWIG与C和Python结合使用,创建一个函数,该函数将NumPy数组作为输入并返回不同的NumPy数组。返回的数组的大小未指定,具体取决于输入数组。不幸的是,当我尝试运行代码时,返回了一个空数组。这里有一个“最小”的例子来说明这个问题。我通过以下方式运行此代码: python setup.py build_ext --inplace python test.py 感兴趣的文件复制如下。请让我知道,如果你知道如何使这段代码返回一个非空的NumPy数组。谢谢 取消条款c: #inc

我的目标是将SWIG与C和Python结合使用,创建一个函数,该函数将NumPy数组作为输入并返回不同的NumPy数组。返回的数组的大小未指定,具体取决于输入数组。不幸的是,当我尝试运行代码时,返回了一个空数组。这里有一个“最小”的例子来说明这个问题。我通过以下方式运行此代码:

python setup.py build_ext --inplace
python test.py
感兴趣的文件复制如下。请让我知道,如果你知道如何使这段代码返回一个非空的NumPy数组。谢谢

取消条款c:

#include "cancelterms.h"
void cancel(double complex* vec, int m, int n, double complex sum[])
{   

    // Some code that processes vec.

    // This is just an example. In practice the following lines will depend on vec.
    sum[0] = 1.0;
    sum[1] = 2.5;
    sum[2] = 3.6;
}
取消条款。h:

#include <stdlib.h>
#include <stdio.h>
#include <complex.h>

void cancel(double complex* vec, int m, int n, double complex sum[]);
test.py:

import cancelterms
import numpy as np

a=np.array([[1.0j,2.0j,3.0j,4.0j,5.0j,6.0j],[-1.0j,-2.0j,-3.0j,6.0j,7.0j,8.0j]])
print cancelterms.cancel(a)

不幸的是,numpy.i太大了,无法粘贴到这里,但我使用了numpy github存储库中的标准numpy.i文件,只做了一点小小的修改,即在类型列表中添加了双复数。

类型映射,…[ANY]类型映射用于具有硬编码维度的数组。对于输入数组,这在中有明确的说明,但也适用于其他数组

例如,它们可以用作:

%apply (double complex ARGOUT_ARRAY1[ANY]) {(double complex sum[5])}
如果函数采用大小为5的数组(由调用方/在包装器代码中分配)

关键是SWIG无法知道argout数组的大小。您的代码编译并运行完全是巧合。看看生成的包装器代码(搜索“wrap\u cancel”),您将看到发生了什么

还有以下类型图:

  • (数据类型*ARGOUT\u数组1,int DIM1)

    您可以在其中指定要预分配的阵列的大小
  • (数据类型**参数视图阵列1,尺寸类型*DIM1)

    其中,数组由函数分配,但还返回已分配数组的大小
在您的例子中,函数
cancel
为数组
sum
分配内存,假设调用者有办法计算出大小。这种情况下没有预定义的类型映射

这类似于函数仅返回一个
双复数*
,如numpy.i文档中所述:

如果遇到函数或方法返回指向数组的指针的情况,最好是编写要包装的函数的自己版本,对于类方法使用%extend,对于函数使用%ignore和%rename

import cancelterms
import numpy as np

a=np.array([[1.0j,2.0j,3.0j,4.0j,5.0j,6.0j],[-1.0j,-2.0j,-3.0j,6.0j,7.0j,8.0j]])
print cancelterms.cancel(a)
%apply (double complex ARGOUT_ARRAY1[ANY]) {(double complex sum[5])}