With some hacking about I got data going back and forth between Python and C using python c-types. It seems a little messy, so I was hoping someone with more experience could tell me if I'm doing something incorrectly, or making this more difficult than it needs to be.
Python Code:
from ctypes import cdll, POINTER, byref, c_double
lib = cdll.LoadLibrary('./test.so')
def alloc_arrays(length, python_list):
# Create array of float*
data = ((POINTER(c_double)) * length)()
out_data = ((POINTER(c_double)) * length)()
for i in xrange(length):
# Create arrays of float
data[i] = (c_double * 3)()
out_data[i] = (c_double * 3)()
# Set Values
for j in xrange(3):
data[i][j] = python_list[i][j]
out_data[i][j] = 0.0
return data, out_data
if __name__ == "__main__":
a = [[1.0, 11.0, 21.0],
[2.0, 12.0, 22.0],
[3.0, 13.0, 23.0],
[4.0, 14.0, 24.0],
[5.0, 15.0, 25.0],
[6.0, 16.0, 26.0],
[7.0, 17.0, 27.0]]
in_data, out_data = alloc_arrays(len(a), a)
out_len = lib.smain(byref(in_data), len(a), out_data)
print "out_len", out_len
clean_out = [None, None, None]
clean_out = [clean_out[:] for i in xrange(out_len)]
for i in xrange(out_len):
for j in xrange(3):
clean_out[i][j] = out_data[i][j]
print "Out:", clean_out
C code (test.c):
int smain(double* in_points[3], int in_len, double* out_points[3]){
int i;
int j;
printf("%s", "\n");
for(i = 0; i < in_len; i++){
for(j = 0; j < 3; j++){
printf("%g, ", *in_points[i][j]);
}
printf("%s", "\n");
}
printf("%s", "\n");
//*out_points = malloc(len*sizeof(float[3]));
int out_len = in_len-2; //Randomly chosen shorter length
for(i = 0; i < out_len; i++){
for(j = 0; j < 3; j++){
//Random function just to see I can do this
*out_points[i][j] = i*j;
}
}
return out_len;
}
To build I use:
gcc -c -fPIC test.c
gcc -shared -o test.so test.o
The main things I'm wondering about are if there are better ways to create empty 2D vectors to pass into C, and if there are beter ways to cast variables to/from ctypes to python types. I don't like the alloc_arrays function having to do the conversion, and I don't like having my for loops read the c_types 2D list (just realized I did it a little messy too).
EDIT: Just want to be clear that this code works as expected, I just think there have to be some ways to improve it.