2011-12-02 29 views
13

Sto provando a chiamare qsort in Cython con una funzione di confronto personalizzata ma non capisco come passare il riferimento alla funzione. In primo luogo, ho una struct:Come passare un puntatore a una funzione c in Cython?

cdef struct Pair: 
    int i,j 
    float h 

Il confronto sorta di funzione da 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 

Questa è la parte che sto avendo problemi 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) 

L'ultima riga ha vinto Compilare e generare questo errore che credo sia legato al fatto che non riesco a capire come passare compare come riferimento a qsort:

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

risposta

9

Non sono stato in grado di riprodurre il tuo errore. Il codice che stai utilizzando è giusto e funziona con Cython 0.15. L'unica cosa che vedo potrebbe essere il tuo errore è il "gil" aggiunto al tipo. Se si desidera dichiarare in modo specifico un metodo importato come "gil safe", aggiungere "nogil" alla fine della dichiarazione.

(nota che è possibile controllare il codice python con Cython -a, allora browser open web per)

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

Questo frammento è compilato come:

 
$ 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

Ho un [annuncio Cython] (http://stackoverflow.com/questions/41944883/verify-compatibility-in-compiling-extension-types-and-using-them-with-cdef) potresti essere in grado di fornire informazioni approfondite. – Phillip

Problemi correlati