2015-09-29 3 views
0

Я хочу выставить буферный протокол для объекта, как и in this example документации Cython, однако мне нужно сделать это с помощью CFFI, и я не смог найти никаких примеров для публикации протокола буфера.Буферный протокол с использованием CFFI

+0

Я не думаю, что это имеет смысл. Реализация буферного протокола в конечном итоге включает в себя [создание некоторых функций C самостоятельно] (https://docs.python.org/3/c-api/buffer.html) и [их добавление к типу, определенному с использованием C-API Python] (https://docs.python.org/3/c-api/typeobj.html#buffer-structs). (В стороне, Cython предоставляет способ сделать это из «кода, подобного Python»). CFFI - это способ вызова существующих библиотек C из Python, но не для написания нового кода C. – DavidW

+0

Не так, см. Метод 'set_source' в этих [docs] (https://cffi.readthedocs.org/en/latest/overview.html#purely-for-performance-api-level-out-ofline). Они также предоставляют 'ffi.buffer () 'метод для возврата объектов буфера, однако эти объекты не выставляют буферный протокол. – Tarantula

+0

Ah - справедливо. Моя ошибка (я думаю). Быстрый просмотр исходного кода для cffi (https://bitbucket.org/cffi /cffi/src/059aca3cb3dc5faa3d54ce4560b28215c686216e/c/minibuffer.h?at=default&fileviewer=file-view-default#minibuffer.h-123) предполагает, что буфер должен выставлять протокол буфера Python. Я не уверен, что понимаю ваш вопрос очень хорошо, но у меня будет немного совать ... – DavidW

ответ

3

Мое прочтение вопроса заключается в том, что у вас есть некоторые данные, которые у вас есть на интерфейсе CFFI, и вы хотите разоблачить его, используя стандартный протокол буфера Python (который использует множество расширений C для быстрого доступа к данным массива).

Хорошая новость ffi.buffer() команда (что, если честно, я не знал, пока OP не упомянул об этом!) Предоставляет как интерфейс Python, так и протокол буфера C-API. Однако он ограничен просмотром данных в виде массива unsigned char/byte. К счастью, используя другие объекты Python (например, memoryview, можно просмотреть его как другие типы).

Остальной частью поста является наглядным примером:

# buf_test.pyx 
# This is just using Cython to define a couple of functions that expect 
# objects with the buffer protocol of different types, as an easy way 
# to prove it works. Cython isn't needed to use ffi.buffer()! 
def test_uchar(unsigned char[:] contents): 
    print(contents.shape[0]) 
    for i in range(contents.shape[0]): 
     contents[i]=b'a' 

def test_double(double[:] contents): 
    print(contents.shape[0]) 
    for i in range(contents.shape[0]): 
     contents[i]=1.0 

... и файл Python с использованием cffi

import cffi 
ffi = cffi.FFI() 

data = ffi.buffer(ffi.new("double[20]")) # allocate some space to store data 
     # alternatively, this could have been returned by a function wrapped 
     # using ffi 

# now use the Cython file to test the buffer interface 
import pyximport; pyximport.install() 
import buf_test 

# next line DOESN'T WORK - complains about the data type of the buffer 
# buf_test.test_double(obj.data) 

buf_test.test_uchar(obj.data) # works fine - but interprets as unsigned char 

# we can also use casts and the Python 
# standard memoryview object to get it as a double array 
buf_test.test_double(memoryview(obj.data).cast('d')) 
+0

Большое спасибо Дэвиду. – Tarantula

Смежные вопросы