我正在使用SWIG和numpy.i将C库暴露给python。我试图包装的函数将一系列double
数组作为参数:
int wcsp2s(struct wcsprm *wcs, int ncoord, int nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]);
其中一些数组实际上是二维的,其范围由ncoord
和nelem
参数给出。这是我遇到问题的这些二维数组,因为numpy.i
似乎只支持int n1
,int n2
,double * arr
或各种排列形式的东西(和我的C函数不需要那些额外的整数)或double arr[ANY][ANY]
。后者看起来很有希望,因为多维C数组只是一个连续的内存块,因此应与函数所期望的兼容。但是当我尝试
%apply (double INPLACE_ARRAY2[ANY][ANY]) {(double imgcrd[]),(double world[])};
SWIG(或者更确切地说是在SWIG的输出上运行的gcc)抱怨:
wcs_wrap.c:3770:7: error: expected expression before ‘,’ token
这里SWIG为这些参数生成了无效的C代码。
我在这里尝试做的可能吗?我想我可以使用%inplace和%rename来创建一个包装函数,它确实接受数组的(不必要的)维度,然后调用实际函数。如果我可以将这些数组作为输出参数返回(甚至比基于ncoord
和nelem
的维度更容易计算,那么使用inplace数组的方法会更好。
也许快速(即不是astLib中的那个)到libwcs的python接口已经存在,所以我不必这样做?
编辑:我刚刚发现pywcs(它有一个明显的名字,我应该在我的初始搜索中找到它),这解决了我的根本问题。
Edit2:我猜一个包含2d numpy数组的包装器传递它的平坦视图会解决问题,因为1d数组似乎有效。但是,最终需要大量文件用于简单的包装器(.i,_wrap.c,.py来自swig和一个额外的.py来进一步包装SWIG函数来修复维度问题。
答案 0 :(得分:0)
我也错过了使用numpy.i
的好食谱。据我了解,您可以:
IN_ARRAY2
或INPLACE_ARRAY2
)。IN_ARRAY2
或INPLACE_ARRAY2
)。ARGOUT_ARRAY1
)时,你必须在从python中调用它时传递大小。在下面的示例中,您将编写oo = func3(20)
。原因似乎是因为python需要分配内存,它需要知道大小,例如,您的.i
- 文件看起来像他的:
...
%include "numpy.i"
%init %{
import_array();
%}
// Pass array of dynamic size:
%apply (double* INPLACE_ARRAY2, int DIM1, int DIM2) {(double *xx, int xx_n, int xx_m)};
void func1(double *xx,int xx_n, int xx_m);
// Pass array of fixed size:
%apply (int *INPLACE_ARRAY2[ANY][ANY]) { (double yy[4][4]) };
void func2(double yy[4][4]);
// Return a dynamic 1D array:
%apply (double* ARGOUT_ARRAY1, int DIM1) {(double* out, int out_n)}
void func3(double* out, int out_n);
当然,您可以将这些结合起来 - 查看the Docs以获取更多信息