Python Cython MemoryView:用数组参数包装c函数以传递numpy数组

Python Cython MemoryView:用数组参数包装c函数以传递numpy数组,python,c,numpy,cython,memoryview,Python,C,Numpy,Cython,Memoryview,我试图使用Cython将c函数包装成一个数组参数(quick\u sort()),这样我就可以向它传递一个numpy数组。我在文档中搜索了一个简单的示例,但没有找到。我尝试过几种可能性,但没有任何进展,所以请帮我弄清楚。这是我的档案: 快速排序.c #include <stdio.h> void quick_sort (int* a, int n) { int i, j, p, t; if (n < 2) return; p = a[n

我试图使用Cython将c函数包装成一个数组参数(
quick\u sort()
),这样我就可以向它传递一个numpy数组。我在文档中搜索了一个简单的示例,但没有找到。我尝试过几种可能性,但没有任何进展,所以请帮我弄清楚。这是我的档案:

快速排序.c

#include <stdio.h>

void quick_sort (int* a, int n) {
    int i, j, p, t;
    if (n < 2)
        return;
    p = a[n / 2];
    for (i = 0, j = n - 1;; i++, j--) {
        while (a[i] < p)
            i++;
        while (p < a[j])
            j--;
        if (i >= j)
            break;
        t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    quick_sort(a, i);
    quick_sort(a + i, n - i);
}
快速排序.pxd

cdef extern from "quicksort.h":
    void quick_sort (int[:] a, int n)
cy\u quicksort.pyx

cimport quicksort

def quicksort_c(int[:] a):
    quicksort.quick_sort(a, a.size)
setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name='quicksort cython',
    ext_modules=cythonize("*.pyx"),
)
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension

sourcefiles = ['cy_quicksort.pyx', 'quicksort.c']

extensions = [Extension("cy_quicksort", sourcefiles)]

setup(
    ext_modules = cythonize(extensions)
)
当我运行
python setup.py build\u ext--inplace
命令时,它返回以下错误:

cy_quicksort.c:1362:14: error: passing '__Pyx_memviewslice' to parameter of
      incompatible type 'int *'
  quick_sort(__pyx_v_a, __pyx_t_3);
             ^~~~~~~~~
./quicksort.h:1:23: note: passing argument to parameter 'a' here
void quick_sort (int* a, int n);
我想要实现的是编译此文件并能够运行,例如:

import numpy as np
from cy_quicksort import quicksort_c
a = np.array(range(9, 0, -1), dtype=np.int32)
quicksort_c(a)
提前感谢您的时间


编辑: DavidW在quicksort.pxdcy_quicksort.pyx中建议进行更改,并将setup.py文件更改为以下格式后,该文件即可正常工作

setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name='quicksort cython',
    ext_modules=cythonize("*.pyx"),
)
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension

sourcefiles = ['cy_quicksort.pyx', 'quicksort.c']

extensions = [Extension("cy_quicksort", sourcefiles)]

setup(
    ext_modules = cythonize(extensions)
)
问题主要出现在“quicksort.pxd”中-定义需要与quicksort.h中的定义相匹配:

cdef extern from "quicksort.h":
    void quick_sort (int* a, int n)
[:]
将其定义为memoryview,这是Cythony的发明,不能直接转换为指针,正如您的错误所述)

然后,您需要从“cy_quicksort.pyx”中的memoryview中获取指针

我已将输入参数更改为
[::1]
,以指定元素在内存中必须是连续的,我认为这是quicksort所期望的


(注意-未经测试,但相当简单,因此应该可以使用!)

感谢您的回答。使用您的修复程序,它可以编译,但是当我尝试
导入cy\u quicksort
时,它会返回
导入错误:dlopen(./cy\u quicksort.so,2):未找到符号:_quick\u sort引用自:./cy\u quicksort.so预期位于:./cy\u quicksort.so中的平面命名空间。您知道会出现什么问题吗?您需要确保在生成模块时编译并链接quicksort.c。看一看(下面的例子)。我认为您需要执行
sourcefiles=['cy_quicksort.pyx','quicksort.c']
,然后按照链接中给出的示例的其余部分进行操作。林克:非常感谢,现在它开始工作了!我会花几个小时试着自己弄明白。。。我已经编辑了我的问题,为任何可能的读者添加了working setup.py。谈论复杂的语法…:D但它有效。我花了很长时间才找到这个信息。谢谢你的回答和解释。@Azeria你可能还没有告诉Cython你正在尝试使用的C函数(因此假设该函数是一个接受Python对象的Python函数)