我有一个是在常规的Python创建的浮点值的阵列,我想传递给一个用Cython功能方面对底层C函数。 C函数需要作为浮动指针如在要传递的数组:
void setOverlays(const float * verts);
在用Cython包装看起来是这样的:
def set_overlays(verts):
setOverlays(verts)
我怎样才能使绿党成用Cython数组? 我认为这可能工作:
cdef float * cVerts = [v for v in verts]
但不幸的是所产生的值是一个Python对象和在这种情况下自动转换不起作用。
在ctypes的等效表达式(即作品)是:
cVerts = (c_float * len(verts))()
for i in range(len(verts)):
cVerts[i] = verts[i]
setOverlays(cast(byteref(cVerts), POINTER(c_float)))
我想达到同样的事情,但在用Cython
提前致谢!
我相信你可以通过遍历彩车的Python列表,并把它们放在一个C数组做到这一点。
cimport cython
from libc.stdlib cimport malloc, free
cdef:
float * cfloats
int i
cfloats = <float *> malloc(len(pyfloats)*cython.sizeof(float))
if cfloats is NULL:
raise MemoryError()
for i in xrange(len(pyfloats)):
cfloats[i] = pyfloats[i]
setOverlays(cfloats)
free(cfloats)
接受的答案是错的,并导致分段错误,因为对于内存float *
从未分配。
@JAB的答案显示的路要走,但我想更详细地说明。
传递数组:
现在的问题是如何将蟒蛇数组转换为C数组。 蟒array
(从array
模块 )是围绕连续存储器的包装,所以没有必要复制的存储器-我们只是可以传递指针到c-功能:
from cpython cimport array
import array
def set_overlays(array.array verts):
setOverlays(verts.data.as_floats)
使用array
模块优于numpy
,因为它是标准库的一部分-有没有需要安装的东西。 该解决方案是短暂的和漂亮,但有一个问题:有人能与使用int-array
会有任何错误-内存只是被重新诠释。 有时它是一个想要的东西,但大多数的时候不是这种情况。
为了确保,即传递的数组对象有正确的类型的数据,存储器视图可用于:
from cpython cimport array #still needed
def set_overlays_memview(float[::1] verts):
setOverlays(&verts[0])
[::1]
确保的是,存储器视图环绕连续存储器。 然而,这种代码有一个问题,如果有在存储视图中没有元件,因为外的边界的访问的, verts[0]
来处理它的正确方法取决于函数setOverlays
,而不是这个答案的一部分。
传递一个列表:
如果我们有一个Python列表传递给C函数,我们要的值复制到一个连续的内存。 使用的功能,最好的做法array
-没有必要重新发明轮子:
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
退房http://docs.cython.org/src/userguide/memoryviews.html 。 看起来它也提供了有关如何利用Python的内置提示array
模块,以及numpy
。
我发现用Cython具体方式:
cdef float* cVerts = []
for i in xrange(len(verts)):
cVerts[i] = verts[i]
setOverlays(cVerts)
有趣的是上述两种溶液由用Cython编译器拒绝。
这是我用准备阵列传递到用Cython或C / CPP与痛饮。
import numpy as np
def make_c_array(a):
"""
Take an input numpy array and convert to being ready for use in C.
"""
b = []
for i in range(len(a)):
b.append(a[i])
a = np.array(b,dtype=np.dtype('d'),order='C')
return a