One problem I can spot in your code is the size of your floats.
Note that it doesn't really matter as a pointer to what you pass pointers to your numpy data to your function. I, for one, am used to pass data as arr.ctypes.data_as(ctypes.c_void_p).
This is dynamic, so it is not like C compiler could check anything. And, at least in this case, there is no dynamic checking neither that in makes senses to consider this numpy array data as a pointer to this type.
So, saying correctly or not as POINTER to what you want to pass a numpy array to a function that expect a float * doesn't protect you against error.
It doesn't neither imply any conversion. The pointer is just passed to the C function, it is up to it to interpret correctly, and that has been done statically, when you typed the parameter float *.
So, it is not there (in the code you seem to be wondering about) that you can ensure that the C function get the bunch of float it expect. Whatever, the C function will get a pointer to the numpy data.
The problem you have in your code is that data in x_spots are not float (as in the C meaning of the word float; that is 32 bits floating point numbers). They are most likely double
I say "most likely" because I am not an expert in different python interpreters. I know that, depending on the interpreter, native float type of python may be float32, or float64 or even something else. In the most classical CPython, they are float64. And I am not sure neither what it means for numpy when dtypes is the native type float. But well, with my cpython, a np.array([1,2,3], dtype=float) is a numpy array made of float64. So, not 100% sure if that is a sure thing, or if it exists python interpreter in which that array would be made of float32. It is because I am unsure of that, that, anyway, I never ever use float as an argument for dtype. I use np.float32 or np.float64.
But, well, most likely (or even surely) your x_spots is made of float64.
And then, it doesn't matter a pointer to what you say it is when you pass x_spots.ctypes.data_as(POINTER(...)), the pointer will be a pointer to those float64. That is, in C wording, to double. And your C function will treat it as a pointer to float (with no warning whatsoever: warning occur at compilation time, and we are past that).
So, long story. But conclusion is, either you
- Change your C function to accept
double * as parameter for this x_spots thing. That's probably the best way, with your, probably 64 bits computer. But you seem to say that you can't really modify the C function
- So, alternatively, you can ensure that your data is made of
float (in C meaning), that is create your x_spots with a dtype=np.float32.
Note that even if you choose the first case (double *), it would be better to change also dtype to explicitly set it to np.float64.
And once you have done that, it doesn't matter if you pass your argument as x_spots.ctypes.data_as(c_void_p), as x_spots.ctypes.data_as(POINTER(c_float)), as x_spots.ctypes.data_as(POINTER(c_double)), or even x_spots.ctypes.data_as(POINTER(c_char)).
(I strongly encourage you, of course, not to use a false type as POINTER() arg, but that is for human readability of your code; from execution change point of view, it wouldn't change the result)
So tl;dr
- Change type of parameter of C function from
float * to double *
- Or, change
dtype of your numpy arrays from float to np.float32
np.arange([0]*number)cannot be real code.