21

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

4

1 に答える 1

2

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

しかし、古いスタイルのバッファを気にしない場合は、ほとんどの場合次のように使用できますmemoryview

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

もちろん、これにはstr(または、3.x ではbytes)、bytearrayなどが含まれます。リンクをたどると、サポート対象を説明するためにリンクしたのと同じページにリンクして、サポート内容を説明していることに気付く場合があります。

文字の 1D 配列 ( などstr) の場合、次のようになります。

cdef char [:] gotdata
于 2014-08-13T08:34:47.870 に答える