You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:08:07