2013-04-20 14 views
20

Daha fazla veri almak için sürekli olarak kullanıcı tarafından sağlanan işlev göstergesini çağıran bir C kütüphanesi ile çalışıyorum. Bu geriçağırımın Python uygulamasının str, bytearray32, bellek eşlemeli dosyalar gibi herhangi bir makul veri türünü döndürebilmesi için bir Cython sarıcısı yazmak istiyorum (özellikle, Buffer interface'u destekler). Ne var bugüne kadar geçerli:Cython'da arabellek API'sini kullanma

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) 

Ben eşdeğer C kodu üretecektir yazma, ancak bu gibi görünmek istiyorum kodu:

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 

oluşturulan C kodu bunu düşündüğünü benziyor yapmalıydı; ama bu Python API'sinde gereksiz yere kazmaya benziyor. Cython bu etkiyi elde etmek için daha güzel bir sözdizimi sağlıyor mu?

cevap

2

Yeni stil veya eski stil arabellek arabiriminin her varyasyonunu uygulayan her şeyi desteklemek istiyorsanız, C API'sini kullanmanız gerekir.

Ama eski tip tamponların umurumda değil, sen hemen hemen her zaman kullanabileceğiniz bir memoryview:

Cython memoryviews destek Python yeni stil tamponların arayüz ihraç neredeyse tüm nesneler. Bu, PEP 3118'de açıklanan tampon arabirimidir. NumPy dizileri, Cython dizileri gibi bu arabirimi destekler. “Neredeyse tüm”, Python arabellek arabiriminin veri dizisindeki öğelerin kendilerine işaretçi olmasına izin vermesidir; Cython hafıza görüntülemeleri henüz bunu desteklemiyor. Bağlantıyı takip

Elbette bu, bytearray, (3.x, bytes ya) str içeriyorsa vb-, bunu size bağlı olduğunu desteklemektedir anlatmaya aynı sayfaya bağlanan fark edebilirsiniz Neyi desteklemek istediğinizi açıklamak. karakterleri (str benzeri) 1D diziler için

, bu kadar:

cdef char [:] gotdata 
İlgili konular