Frage Wie übergebe ich einen Zeiger auf eine c-Funktion in Cython?


Ich versuche Anruf qsort in Cython mit einer benutzerdefinierten Vergleichsfunktion, aber ich verstehe nicht, wie die Funktionsreferenz übergeben wird. Zuerst habe ich eine Struktur:

cdef struct Pair:
    int i,j
    float h

Die Vergleichsfunktion sortiert nach 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

Dies ist der Teil, mit dem ich Probleme habe:

    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)

Die letzte Zeile wird nicht kompiliert und erzeugt diesen Fehler, von dem ich glaube, dass er mit der Tatsache zusammenhängt, dass ich nicht herausfinden kann, wie ich vorgehen soll compare als Referenz zu qsort:

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

13
2017-12-02 07:31


Ursprung


Antworten:


Ich konnte Ihren Fehler nicht reproduzieren. Der Code, den Sie verwenden, ist richtig und funktioniert mit Cython 0.15. Die einzige Sache, die ich sehe, dass Ihr Fehler sein könnte, ist das "gil", das an den Typ angehängt wird. Wenn Sie eine importierte Methode explizit als "gil safe" deklarieren möchten, hängen Sie "nogil" am Ende der Deklaration an.

(Beachten Sie, dass Sie Ihren Python-Code mit Cython -a überprüfen können, öffnen Sie dann den Webbrowser für)

cdef extern von "stdlib.h":
    ctypedef void const_void "const void"
    void qsort (void * Basis, int nmemb, int Größe,
            int (* Vergleich) (const_void *, const_void *)) nogil

cdef-struct-Paar:
    int i, j
    float h

cdef int vergleichen (const_void * a, const_void * b):
    cdef float v = ((a)). h - ((b)). h
    Druck 'etwas mit machen', v
    Wenn v 0: 1 zurückgeben
    zurückgeben 0

def r ():
    cdef Paar [5] pa
    für i in Reichweite (5):
        pa [i] .i = i;
        pa [i] .j = i * 2;
        pa [i] .h = i * .5;
    Druck 'Anruf qsort'
    qsort (pa, 5, sizeof (Paar), vergleichen)
    Druck 'Anruf qsort erledigt'

r ()

Dieses Snippet wird wie folgt kompiliert:

$ 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
rufe qsort an
mach etwas mit -0,5
mach etwas mit -0,5
mach etwas mit -0,5
Mach etwas mit -1.0
mach etwas mit -0,5
rufe qsort auf

9
2017-12-02 09:00