2011-12-02 21 views
13

Estoy tratando de llamar al qsort en Cython con una función de comparación personalizada, pero no entiendo cómo pasar la referencia de la función. En primer lugar, tengo una estructura:¿Cómo paso un puntero a una función c en Cython?

cdef struct Pair: 
    int i,j 
    float h 

La comparar tipo de función por 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 

Esta es la parte que estoy teniendo problemas con:

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) 

La última línea ganó No compilo y genero este error que creo que está relacionado con el hecho de que no puedo entender cómo pasar compare como referencia al qsort:

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

Respuesta

9

No he podido reproducir su error. El código que estás usando es el correcto y estás trabajando con Cython 0.15. Lo único que veo que podría ser su error es el "gil" adjunto al tipo. Si desea declarar específicamente un método importado como "gil safe", añada "nogil" al final de la declaración.

(nota que se puede comprobar el código Python en -a Cython, entonces navegador web abierto para)

 
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() 

Este fragmento de código se compila como:

 
$ 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 
+0

Tengo un [post Cython] (http://stackoverflow.com/questions/41944883/verifying-compatibility-in-compiling-extension-types-and-using-them-with-cdef) es posible que pueda proporcionar información sobre. – Phillip

Cuestiones relacionadas