如何转换蟒蛇阵用Cython数组?(How to convert python array to c

2019-06-26 13:51发布

我有一个是在常规的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

提前致谢!

Answer 1:

我相信你可以通过遍历彩车的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)


Answer 2:

接受的答案是错的,并导致分段错误,因为对于内存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


Answer 3:

退房http://docs.cython.org/src/userguide/memoryviews.html 。 看起来它也提供了有关如何利用Python的内置提示array模块,以及numpy



Answer 4:

我发现用Cython具体方式:

cdef float* cVerts = []
    for i in xrange(len(verts)):
        cVerts[i] = verts[i]
setOverlays(cVerts)

有趣的是上述两种溶液由用Cython编译器拒绝。



Answer 5:

这是我用准备阵列传递到用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


文章来源: How to convert python array to cython array?