Swig, returning an array of doubles

别等时光非礼了梦想. 提交于 2019-12-04 03:01:32
kynan

The first problem is that your typemap doesn't match, you'll need a %typemap(out) double * { ... } since your function returns a pointer to double and not a double array.

If your list is of fixed size (i.e. an integer literal) as in the example you gave (which I assume is not what you want) you could simply change the typemap as I gave above and exchange $1_dim0 for the fixed size.

Otherwise your problem is that your %typemap(out) double * cannot possibly know the value of your parameter int x. You could return a struct that carries both the pointer and the size. Then you can easily define a typemap to turn that into a list (or a NumPy array, see also my response to Wrap C struct with array member for access in python: SWIG? cython? ctypes?).

Incidentally it's not possible to return a fixed sized array in C (see also this answer: Declaring a C function to return an array), so a %typemap(out) double [ANY] { ... } can never match.

I suffered similar problem and solved it in following way.

// example.i

%module example

%include "carrays.i"
%array_class(float, floatArray);

float * FloatArray(int N);

float SumFloats(float * f);

 

# ipython

> a = example.floatArray(23) # array generated by swig's class constructor

> a

<example.floatArray; proxy of <Swig Object of type 'floatArray *' at 0x2e74180> >

> a[0]

-2.6762280573445764e-37 # unfortunately it is created uninitialized..

> b = example.FloatArray(23) # array generated by function

> b

<Swig Object of type 'float *' at 0x2e6ad80>

> b[0]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
# .....
TypeError: 'SwigPyObject' object is not subscriptable

> #But there is a way to access b!!

> p = example.floatArray_frompointer(b) # i found this function by example. and twice tab

> p

<example.floatArray; proxy of <Swig Object of type 'floatArray *' at 0x2e66750> >

> p[0]

0.0

> p[0] = 42

> p[0]

42.0

Fortunately, all of these types (float *, floatArray *, and proxy of floatArray *) may be successfully passed to C++ function (such as SumFloats).

You might want to look at the documentation around carray.i:

%include "carrays.i" %array_class(int, intArray);

http://www.swig.org/Doc2.0/Python.html#Python_nn48

If you don't mind pulling in the numpy python module in your python code, you can do the following:

In the SWIG interface file:

%{
#define SWIG_FILE_WITH_INIT
%}
%include "numpy.i"
%init %{
import_array();
%}

%apply(float ARGOUT_ARRAY1[ANY]) {(float outarray1d[9])};
void rf(float outarray1d[9]);

Only the last two lines are specific to this example, the first stuff is default for numpy.i (see the numpy.i documentation elsewhere: http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html).

In the C file (can also be inlined in .i file):

void rf(float outarray1d[9]) {
    float _internal_rf[9];
    /* ... */
    memcpy(outarray1d, _internal_rf, 9*sizeof(float));
}

Then you have a function which you can call from python as

import mymodule
a = mymodule.rf()
# a is a numpy array of float32's, with len 9

Now, if you don't want to be forced to pull in the numpy module in your python project, then I suggest you check numpy.i to see how they do the %typemap trick -- as I understand it, it's done with SWIG typemaps and not inherently tied to numpy - should be possible to do the same trick with tuples or lists as return value.

I don't know how much C you know - so apologies if I'm teaching you to suck eggs here...

There is no Array class in plain-ole C. An array is always a pointer to a piece of memory, not a "thing" in itself and therefore cannot just be printed-out by itself.

In this case - your "buf" is of type "double *". AFAICRem, if you want to print out the actual values stored at "the memory pointed-to by buf" you have to deallocate each one eg (in pseudocode): for i = 0 to buflength print buf[i]

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!