私は、ユーザーが提供する関数ポインターを繰り返し呼び出してより多くのデータを取得する C ライブラリを使用しています。str
そのコールバックの Python 実装が、bytearray
、メモリ マップ ファイルなどの適切なデータ型を返すことができるような方法で Cython ラッパーを作成したいと思います (具体的には、 Buffer インターフェイスをサポートします)。私がこれまでに持っているものは次のとおりです。
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コードを生成しますが、次のようになります。
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
生成された C コードは、私がやるべきだと思っていることのように見えます。しかし、これは不必要に Python API を掘り下げているようです。Cython は、この効果を達成するためのより優れた構文を提供していますか?