views:

49

answers:

1

Hi there,

I have C code which uses a variable data, which is a large 2d array created with malloc with variable size. Now I have to write an interface, so that the C functions can be called from within Python. I use ctypes for that.

C code:

FOO* pytrain(float **data){
    FOO *foo = foo_autoTrain((float (*)[])data);
    return foo;
}

with

FOO *foo_autoTrain(float data[nrows][ncols]) {...}

Python code:

autofoo=cdll.LoadLibrary("./libfoo.so")
... data gets filled ...
foo = autofoo.pytrain(pointer(pointer(p_data)))

My problem is, that when I try to access data in foo_autoTrain I only get 0.0 or other random values and a seg fault later. So how could I pass float (*)[])data to foo_autoTrain in Python?

Please don't hesitate to point out, if I described some part of my problem not sufficient enough.

A: 

It looks to me like the issue is a miscomprehension of how multidimensional arrays work in C. An expression like a[r][c] can mean one of two things depending on the type of a. If the type of a were float **, then the expression would mean a double pointer-offset dereference, something like this if done out long-hand:

float *row = a[r]; // First dereference yields a pointer to the row array
return row[c]      // Second dereference yields the value

If the type of a were instead float (*)[ncols], then the expression becomes simply shorthand for shaping a contiguous, one-dimensional memory region as a multi-dimensional array:

float *flat = (float *)a;
return flat[(r * ncols) + c]; // Same as a[r][c]

So in your C code, the type of pytrain()'s argument should be either float * or float (*)[ncols] and your Python code should look something like the following (assuming you're using NumPy for your array data):

c_float_p = ctypes.POINTER(ctypes.c_float)
autofoo.pytrain.argtypes = [c_float_p]
data = numpy.array([[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]], dtype=numpy.float32)
data_p = data.ctypes.data_as(c_float_p)
autofoo.pytrain(data_p)

And if you are in fact using NumPy, check out the ctypes page of the SciPy wiki.

llasram