Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从Cdef函数返回数组_Python_Arrays_Cython - Fatal编程技术网

Python 从Cdef函数返回数组

Python 从Cdef函数返回数组,python,arrays,cython,Python,Arrays,Cython,我想制作一个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-a

我想制作一个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
我可以在纯c中实现同样的功能,但在cython中不行:(

所以我仍然有一些地方做错了。有什么建议吗?

len()
是一个只在python对象上工作的python函数。这就是它无法编译的原因。
对于C数组,您可以用
n=sizeof(array)/sizeof(double)
替换
n=len(array)
,您可能想看看缓冲区接口。它们为类似数组的数据结构(如底层numpy数组)提供了一个很好的接口,但也可以用于处理C数组。从文档中可以看到:

例如,它们可以处理C数组和Cython数组类型()

在您的情况下,这可能会有帮助:

cdef test(double[:] array) except? -2:
    ...

double[:]
允许将所有1d双数组传递给函数。然后可以修改这些数组。由于
[:]
定义了一个memoryview,所有更改都将在创建memoryview的数组中进行(作为参数传递给
test
的变量).

您必须发布错误消息。我将对此进行调查
   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>
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
import ctest
a = [0,0,0]
ctest.ctest(a)
cdef test(double[:] array) except? -2:
    ...