I'm using SWIG with numpy.i to expose a C library to python. The function I'm trying to wrap takes a series of double
arrays as arguments:
int wcsp2s(struct wcsprm *wcs, int ncoord, int nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]);
where some of the arrays are actually two-dimensional, with the extent given by the ncoord
and nelem
arguments. It's these two-dimensional arrays I'm having trouble with, since numpy.i
only seems to support things of the form int n1
, int n2
, double * arr
or various permutations (and my C function does not want those extra integers), or double arr[ANY][ANY]
. The latter looked promising, as a multidimensional C array is just a contiguous block of memory, and so should be compatible with what the function expects. But when I try
%apply (double INPLACE_ARRAY2[ANY][ANY]) {(double imgcrd[]),(double world[])};
SWIG (or rather gcc running on SWIG's output) complains:
wcs_wrap.c:3770:7: error: expected expression before ‘,’ token
Here SWIG has generated invalid C code for those arguments.
Is what I'm trying to do here possible? I guess I could use %inplace and %rename to create a wrapper function that does take in the (unnecessary) dimensions of the arrays, and then calls the real function. Even better than the approach above with inplace arrays would be if I could return these arrays as output arguments (their dimensions are easy to calculate based on ncoord
and nelem
.
Or perhaps a fast (ie not the one in astLib) python interface to libwcs already exists, so I don't have to do this?
Edit: I just discovered pywcs (which has such an obvious name that i should have found it during my initial search), which solves my underlying problem.
Edit2: I guess a wrapper that takes in a 2d numpy arrays ans passes on a flattened view of it would get around the problem, since 1d arrays seem to work. Still, that ends up requiring a large amount of files for a simple wrapper (.i, _wrap.c, .py from swig and an additional .py to further wrap the SWIG functions to fix the dimensionality problem.
I am also missing a good cookbook for using numpy.i
. As far as I understand, you can either:
IN_ARRAY2
or INPLACE_ARRAY2
). IN_ARRAY2
or INPLACE_ARRAY2
). ARGOUT_ARRAY1
), you have to pass the size when calling it from python. In the example below, you would write oo = func3(20)
. The reason seems to be since python needs to allocate the memory, it needs to know about the size, For example, your .i
-file could look like his:
...
%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);
Of course you can combine these - check the Docs for more information
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.