私は、より多くのデータを得るためにユーザー指定の関数ポインタを繰り返し呼び出す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はこの効果を達成するためのより良い構文を提供しますか?