如何用Cython将C char数组读取到Python bytearray或可Pickle结构?
如何将C的char数组转换为Python的bytearray(支持pickle序列化)
嘿,这俩问题其实是同一个场景的不同问法,我来给你讲清楚怎么搞定~
最直接的方案:用bytearray构造函数直接转换
Cython对Python的bytearray构造函数做了优化,支持直接传入C的char*指针和数组长度size_t,它会自动复制C数组里的数据到Python管理的内存中——这很重要,因为这样即使原C数组被释放,你的Python bytearray依然安全,而且bytearray本身就是标准Python类型,完美支持pickle序列化。
代码示例:
# 假设你已经有了初始化好的C数组指针和长度 cdef char *bp cdef size_t size # 直接转换为bytearray py_bytearray = bytearray(bp, size)
关键细节提醒:
- 这个方法会按
size指定的长度读取数据,不会被NULL字节截断,非常适合处理二进制数据(比如图片、自定义协议包这类)。 - 如果你的C数组是文本字符串(带NULL终止符),也可以用
str(bp),但那是处理文本的场景,你的问题里明确是字节数组,所以优先用bytearray或bytes。
完整的Cython函数示例
下面是一个可运行的完整例子,包含内存分配、数据填充、转换和内存释放:
from cpython.mem cimport PyMem_Malloc, PyMem_Free def get_serializable_bytearray(): # 定义数组大小 cdef size_t size = 16 # 分配C内存(用PyMem_Malloc方便和Python内存管理兼容) cdef char *bp = <char*>PyMem_Malloc(size) if not bp: raise MemoryError("Failed to allocate C memory") # 给C数组填充测试数据(比如0到15的字节) for i in range(size): bp[i] = i # 转换为Python bytearray(自动复制数据) py_ba = bytearray(bp, size) # 释放原C内存,因为bytearray已经持有了复制后的数据 PyMem_Free(bp) return py_ba
验证pickle序列化
拿到bytearray后,直接用pickle序列化完全没问题:
import pickle # 获取bytearray ba = get_serializable_bytearray() # 序列化 pickled_data = pickle.dumps(ba) # 反序列化 restored_ba = pickle.loads(pickled_data) # 验证数据一致 assert restored_ba == ba
备选方案:用bytes类型
如果你不需要可变的字节数组,也可以用bytes(bp, size)来转换——bytes是不可变的,同样支持pickle,用法和bytearray几乎一致,看你的需求选择就行。
内容的提问来源于stack exchange,提问作者The Unfun Cat
相关产品推荐
相关产品推荐

