The accepted answer is wrong and leads to a segmentation fault, because the memory for the float *
is never allocated.
The answer of @JAB shows the way to go, but I would like to elaborate more.
Passing an array:
The question is how to convert python array to an c-style array. Python array
(from the array
module) is a wrapper around continuous memory, so there is no need to copy the memory - we just can pass the pointer to the c-function:
from cpython cimport array
import array
def set_overlays(array.array verts):
setOverlays(verts.data.as_floats)
Using array
module is better than numpy
because it is part of the standard library - there is no need to install something. This solution is short and nice, but has a problem: somebody could use it with an int-array
and there will be no error - the memory just gets reinterpreted. Sometimes it is what one wants, but most of the time this is not the case.
To make sure, that the passed array-object has the right type of data, memory views can be used:
from cpython cimport array #still needed
def set_overlays_memview(float[::1] verts):
setOverlays(&verts[0])
[::1]
ensures, that the memory view wraps around continuous memory. However, this code has a problem if there are no elements in the memory view,because of the out-of-bounds-access verts[0]
. The right way to handle it depends on the function setOverlays
and is not a part of this answer.
Passing a list:
If we have to pass a python list to the c-function, we have to copy the values to a continuous memory. Best done using the functionality of array
- there is no need to reinvent the wheel:
from cpython cimport array
import array
def set_overlays_list(list verts):
cdef array.array a = array.array('f', verts)
setOverlays(a.data.as_floats) #we already know they are floats