简体   繁体   English

使用CFFI的缓冲区协议

[英]Buffer protocol using CFFI

我想公开一个对象的缓冲协议,就像 Cython文档的示例中一样,但是我需要使用CFFI来做到这一点,而我找不到任何公开缓冲协议的示例。

My reading of the question is that you have some data you've got from a CFFI interface and want to expose it using the standard Python buffer protocol (which lots of C extensions use for quick access to array data). 我对问题的理解是,您已经从CFFI接口中获取了一些数据,并希望使用标准的Python缓冲区协议(很多C扩展用于快速访问数组数据)公开这些数据。

The good news ffi.buffer() command (which, in fairness, I didn't know about until OP mentioned it!) exposes both a Python interface and the C-API side buffer protocol. 好消息ffi.buffer()命令(公平地讲,直到OP提到它,我才知道!)同时公开了Python接口和C-API侧缓冲区协议。 It is restricted to viewing the data as an unsigned char/byte array though. 但是,只能将数据查看为无符号字符/字节数组。 Fortunately, using other Python objects (eg a memoryview it's possible to view it as other types). 幸运的是,使用其他Python对象(例如memoryview ,可以将其视为其他类型)。

Remainder of the post is an illustrative example: 该帖子的其余部分是一个说明性示例:

# 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

... and the Python file using cffi ...以及使用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'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM