我想在c风格中创建一个纯函数,它将数组作为参数(指针)并用它做一些事情。但我无法找到如何为cdef函数定义数组参数。这是我制作的一些玩具代码。
cdef void test(double[] array ) except? -2:
cdef int i,n
i = 0
n = len(array)
for i in range(0,n):
array[i] = array[i]+1.0
def ctest(a):
n = len(a)
#Make a C-array on the heap.
cdef double *v
v = <double *>malloc(n*sizeof(double))
#Copy in the python array
for i in range(n):
v[i] = float(a[i])
#Calling the C-function which do something with the array
test(v)
#Puttint the changed C-array back into python
for i in range(n):
a[i] = v[i]
free(v)
return a
代码无法编译。已经搜索了如何在Cython中定义C数组,但还没有找到如何做到这一点。 double []数组显然不起作用。也尝试过:
cdef void test(double* array ) except? -2:
我可以设法在纯c中做同样的事情,但不能在cython中做同样的事情:(
D:\cython-test\ python setup.py build_ext --inplace
Compiling ctest.pyx because it changed.
[1/1] Cythonizing ctest.pyx
Error compiling Cython file:
------------------------------------------------------------
...
from libc.stdlib cimport malloc, free
cdef void test(double[] array):
cdef int i,n
n = len(array)
^
------------------------------------------------------------
ctest.pyx:5:17: Cannot convert 'double *' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
from libc.stdlib cimport malloc, free
cdef void test(double[] array):
cdef int i,n
n = len(array)
for i in range(0,len(array)):
^
------------------------------------------------------------
ctest.pyx:6:30: Cannot convert 'double *' to Python object
Traceback (most recent call last):
File "setup.py", line 10, in <module>
ext_modules = cythonize("ctest.pyx"),
File "C:\Anaconda\lib\site-packages\Cython\Build\Dependencies.py", line 877, i
n cythonize
cythonize_one(*args)
File "C:\Anaconda\lib\site-packages\Cython\Build\Dependencies.py", line 997, i
n cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: ctest.pyx
E:\GD\UD\Software\BendStiffener\curvmom>
更新
在所有建议之后更新了我的代码并且它现在编译:)但我的数组仍然没有更新。我希望所有条目都应该用5.0更新,但它们不会
from libc.stdlib cimport malloc, free
cdef void test(double[] array):
cdef int i,n
n = sizeof(array)/sizeof(double)
for i in range(0,n):
array[i] = array[i]+5.0
def ctest(a):
n = len(a)
#Make a C-array on the heap.
cdef double* v
v = <double*>malloc(n*sizeof(double))
#Copy in the python array
for i in range(n):
v[i] = float(a[i])
#Calling the C-function which do something with the array
test(v)
#Puttint the changed C-array back into python
for i in range(n):
a[i] = v[i]
free(v)
for x in a:
print x
return a
这是一个用于测试我的代码的python测试程序:
import ctest
a = [0,0,0]
ctest.ctest(a)
所以我仍然做错了。有什么建议吗?
答案 0 :(得分:0)
len()
是一个python函数,仅适用于python对象。这就是为什么它不会编译。
对于C阵列,您可以将n=len(array)
替换为n = sizeof(array) / sizeof(double)
。
答案 1 :(得分:0)
您可能需要查看typed memoryviews和缓冲区界面。这些为数组提供了一个很好的接口,比如那些基于numpy数组的数据结构,但也可以用来处理C数组。来自文档:
例如,他们可以处理C数组和Cython数组类型(Cython arrays)。
在您的情况下,这可能有所帮助:
cdef test(double[:] array) except? -2:
...
double[:]
允许将所有1d双数组传递给函数。那些可以修改。由于[:]
定义了一个内存视图,所有更改都将在您创建内存视图的数组中进行(您作为参数传递给test
的变量)。