15 votes

Comment passer un pointeur à une fonction c en Cython ?

J'essaie d'appeler qsort en Cython avec une fonction de comparaison personnalisée mais je ne comprends pas comment passer la référence de la fonction. Tout d'abord, j'ai une structure :

cdef struct Pair:
    int i,j
    float h

La fonction de comparaison trie par 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

C'est la partie avec laquelle j'ai des problèmes :

    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 dernière ligne ne compile pas et génère cette erreur qui, je pense, est liée au fait que je n'arrive pas à trouver comment passer compare en tant que référence à qsort :

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

9voto

tito Points 5350

Je n'ai pas été en mesure de reproduire votre erreur. Le code que vous utilisez est correct et fonctionne avec Cython 0.15. La seule chose que je vois qui pourrait être votre erreur est le "gil" ajouté au type. Si vous voulez déclarer spécifiquement une méthode importée comme "gil safe", ajoutez "nogil" à la fin de la déclaration.

(notez que vous pouvez vérifier votre code python avec cython -a , puis ouvrir le navigateur web pour )

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

Cet extrait est compilé comme :

$ 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X