如何在Cython中传递指向c函数的指针?

时间:2011-12-02 07:31:38

标签: cython

我正在尝试使用自定义比较函数在Cython中调用qsort,但我不明白如何传递函数引用。首先,我有一个结构:

cdef struct Pair:
    int i,j
    float h

比较功能按h排序:

cdef int compare(const_void *a, const_void *b):
    cdef float v = ((<Pair*>a)).h-((<Pair*>b)).h
    if v < 0: return -1
    if v > 0: return 1
    return 0

这是我遇到问题的部分:

    cdef Pair[5] pa
    for i in range(5):
        pa[i].i = i;
        pa[i].j = i*2;
        pa[i].h = i*.5;
    qsort(pa,5,sizeof(Pair),compare)

最后一行不会编译并生成此错误,我认为这与我无法弄清楚如何将compare作为对qsort的引用的事实有关:

Cannot assign type 'int (const_void *, const_void *)' to 'int (*)(const_void *, const_void *) nogil'

1 个答案:

答案 0 :(得分:9)

我无法重现您的错误。您正在使用的代码是正确的,并使用Cython 0.15。我唯一看到的可能是你的错误是附加在类型上的“gil”。如果您想将导入的方法专门声明为“gil safe”,请在声明的末尾附加“nogil”。

(请注意,您可以使用cython -a检查您的python代码,然后打开Web浏览器)

cdef extern from "stdlib.h":
    ctypedef void const_void "const void"
    void qsort(void *base, int nmemb, int size,
            int(*compar)(const_void *, const_void *)) nogil

cdef struct Pair:
    int i,j
    float h

cdef int compare(const_void *a, const_void *b):
    cdef float v = ((a)).h-((b)).h
    print 'do something with', v
    if v  0: return 1
    return 0

def r():
    cdef Pair[5] pa
    for i in range(5):
        pa[i].i = i;
        pa[i].j = i*2;
        pa[i].h = i*.5;
    print 'call qsort'
    qsort(pa,5,sizeof(Pair),compare)
    print 'call qsort done'

r()

此代码段编译为:

$ cython --version
Cython version 0.15
$ cython --embed test.pyx
$ gcc -I/usr/include/python2.7 -Wall -std=c99 test.c -lpython2.7
$ ./a.out 
call qsort
do something with -0.5
do something with -0.5
do something with -0.5
do something with -1.0
do something with -0.5
call qsort done