2013-04-20 7 views
20

私は、より多くのデータを得るためにユーザー指定の関数ポインタを繰り返し呼び出すCライブラリを使用しています。私はそのコールバックのPython実装がstr,bytearray、メモリマップされたファイルなどのような合理的なデータ型を返すような方法でCythonラッパーを作成したいと思います(具体的にはBuffer interfaceをサポートしています)。私がこれまで持っていることは次のとおりです。CythonでバッファAPIを使用する

from cpython.buffer cimport PyBUF_SIMPLE 
from cpython.buffer cimport Py_buffer 
from cpython.buffer cimport PyObject_GetBuffer 
from cpython.buffer cimport PyBuffer_Release 
from libc.string cimport memmove 

cdef class _callback: 
    cdef public object callback 
    cdef public object data 

cdef uint16_t GetDataCallback(void * userdata, 
           uint32_t wantlen, unsigned char * data, 
           uint32_t * gotlen): 

    cdef Py_buffer gotdata 
    box = <_callback> userdata 
    gotdata_object = box.callback(box.data, wantlen) 
    if not PyObject_CheckBuffer(gotdata_object): 
     # sulk 
     return 1 

    try: 
     PyObject_GetBuffer(gotdata_object, &gotdata, PyBUF_SIMPLE) 

     if not (0 < gotdata.len <= wantlen): 
      # sulk 
      return 1 

     memmove(data, gotdata.buf, gotdata.len) 

     return 0 
    finally: 
     PyBuffer_Release(&gotdata) 

私はを書きたいコードは同等のCコードを生成しますが、次のようになります。生成されたCコードは、私はそれだと思うもののように見えます

from somewhere cimport something 
from libc.string cimport memmove 

cdef class _callback: 
    cdef public object callback 
    cdef public object data 

cdef uint16_t GetDataCallback(void * userdata, 
           uint32_t wantlen, unsigned char * data, 
           uint32_t * gotlen): 


    cdef something gotdata 
    box = <_callback> userdata 
    gotdata = box.callback(box.data, wantlen) 
    if not (0 < gotdata.len <= wantlen): 
     # sulk 
     return 1 

    memmove(data, gotdata.buf, gotdata.len) 

    return 0 

やっているはずです。これはPython APIを不必要に掘り下げているようです。 Cythonはこの効果を達成するためのより良い構文を提供しますか?

答えて

2

新しいスタイルまたは古いスタイルのバッファインターフェイスのすべてのバリエーションを実装するすべてをサポートする場合は、C APIを使用する必要があります。

しかし、あなたは古いスタイルのバッファを気にしないならば、あなたはほとんど常にmemoryviewを使用することができます。

CythonのmemoryviewsはPythonの新しいスタイル・バッファのインターフェースをエクスポートするほぼすべてのオブジェクトをサポートしています。これはPEP 3118で説明されているバッファインタフェースです。NumPy配列はCython配列と同様にこのインタフェースをサポートしています。 "ほぼすべて"というのは、Pythonのバッファインタフェースでは、データ配列の要素自体がポインタになるためです。 Cythonのメモリビューはこれをまだサポートしていません。当然の

このETC-場合、str(または、3.xでは、bytes)、bytearrayが含まれますが、リンクをたどっ、あなたはそれはあなたがリンクされていることをサポートするものを説明するために、同じページにリンクすることがありあなたがサポートしたいことを説明する。文字の1Dアレイについて

strなど)、それは次のとおり

cdef char [:] gotdata 
関連する問題