Reputation: 424
This is a 2 part question. To give some background, I have a C code as follows:
int c_func(const char* dir, float a, float b, float c, float d )
{
printf("%s\n", dir);
printf("%f\n",a);
printf("%f\n",b);
printf("%f\n",c);
printf("%f\n",d);
return 0;
}
This is a simple function that takes in a string and 4 floats as arguments and prints them out I am trying to test my phython/C interface. My python code is as follows:
calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")
calling_function.c_func("hello",1, 2, 3, 4])
Now since this works, instead of passing 4 individual floats, I would like to pass in a list of 4 floats. I have tried different code online to edit my C function so that it takes in a list as one of its parameters but I cant seem to figure out how to do so as I am a new programmer and I am not experienced with C.
Question 1: How do I code a C function to accept a list as its arguments?
Question 2: This list of four floats is actually coming from a list of lists from my python code. After coding the C function would I be able to use a numpy array called testfv2[0,:]
as an input of the C function?testfv2[0,:]
is a list of dimensions 1x4 and testfv2
is a list of dimensions 117x4. For now, I would like to into the C function 1 row at a time which is why I thought using testfv2[0,:]
.
Upvotes: 3
Views: 5883
Reputation: 567
How do I code a C function to accept a list as its arguments?
Short answer, you can't.
Long answer: C does not have lists, but has arrays and pointers.
You have several options then:
int c_func(const char *dir, float abcd[4]) { // using an array with explicit size
int c_func(const char *dir, float abcd[]) { // Using an array (will decay to a pointer at compile-time)
int c_func(const char *dir, float *abcd) { // Using a pointer.
If you will only ever receive 4 floats, I'd suggest the first form, which enforces the size of the array, any user (and mainly your future self) of your function will know to give only an array of four elements.
Calling your function from Python:
floats = [1.0, 2.0, 3.0, 4.0] # Or whatever values you want to pass, but be sure to give only 4
FloatArray4 = ctypes.c_float * 4 # Define a 4-length array of floats
parameter_array = FloatArray4(*floats) # Define the actual array to pass to your C function
I don't know if passing more than 4 floats to FloatArray4
raises an error -- I guess so, but I can't check right now.
As for your second question, if you want dynamic sized arrays (more than 4 elements), you'll have to you one of the other two profiles for your C function, in which case I advise you to put an extra int
argument for the size of the array:
int c_func(const char *dir, float floats[], int size) {
or
int c_func(const char *dir, float *floats, int size) {
You can also use the standard size_t
instead of int
, it's designed just for that.
I you want to pass a multidimensional array, you add another pair of brackets:
int c_func(const char *dir, float floats[][4]) { // Note the explicit size for second dimension
but remember that for a C array, for all dimensions but the first, the dimensions must be explicitly specified. If the value is constant it wont be an issue, however if not you will have to use a pointer instead:
int c_func(const char *dir, float *floats[]) {
or
int c_func(const char *dir, float **floats) {
which are two identical syntaxs (the array will decay to a pointer). Once again, if your dimensions are dynamic, I suggest to add parameters for the size.
If you want supplementary dimensions, just repeat that last step.
Upvotes: 11