2011-12-02 13 views
13

カスタム比較関数を使用してCythonでqsortを呼び出そうとしていますが、関数参照を渡す方法がわかりません。Cythonのc関数へのポインタを渡すにはどうすればよいですか?

cdef struct Pair: 
    int i,j 
    float h 

hにより、関数の種類を比較します:

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) 

最後の行は勝った:

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 

これは私がとのトラブルを抱えている部分である第一に、私は構造体を持っています私はコンパイルして、このエラーを生成します。これは、qsortへの参照としてcompareを渡す方法を理解できないという事実に関連していると信じています。

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

答えて

9

エラーを再現できませんでした。使用しているコードは正しく、Cython 0.15で作業しています。あなたのエラーであるかもしれない私が見る唯一のものは、タイプに追加された "gil"です。インポートされたメソッドを "gil safe"として明示的に宣言したい場合は、宣言の最後に "nogil"を追加します。

として

(あなたがcythonの-a、ため、その後のオープンWebブラウザを使用してPythonコードを確認することができます注)

 
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ポスト]を持っている

 
$ 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

(http://stackoverflow.com/questions/41944883/verifying-compatibility-in-compiling-extension-types-and-using-them-with-cdef)あなたは洞察力を提供することができます。 – Phillip

関連する問題