使用CFFI的缓冲协议

时间:2015-09-29 20:07:12

标签: python c cython python-cffi

我想公开一个对象的缓冲协议,就像Cython文档的in this example一样,但是我需要使用CFFI执行此操作,我无法找到任何要公开的示例缓冲协议。

1 个答案:

答案 0 :(得分:3)

我对这个问题的解读是,您从CFFI接口获得了一些数据,并希望使用标准的Python缓冲协议(许多C扩展用于快速访问数组数据)来公开它。

好消息ffi.buffer()命令(公平地说,直到OP提到它我才知道!)公开了Python接口和C-API端缓冲协议。但是,它仅限于将数据视为无符号字符/字节数组。幸运的是,使用其他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

...和使用cffi的Python文件

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'))