如何向CFFI扩展传递字符串列表?
用CFFI向接收char**参数的C扩展传递字符串列表的正确方式
问题背景
需要向一个以char**作为输入参数的CFFI扩展传递字符串列表,已完成C头文件、实现代码、CFFI构建脚本及Python测试脚本的编写,但尝试以下方式均触发类型错误:
- 传递原生Python字符串列表
- 传递编码后的字节列表
- 直接创建cdata列表
错误提示为:*ctype 'char '初始化需cdata指针,寻求优先无需复制列表的正确传递方案。
正确实现方案
在Python测试脚本(如demo.py)中按以下步骤操作:
- 编码字符串并创建C风格字符数组:将每个Python字符串编码为字节后,通过
ffi.new创建char[]对象,这一步会在C堆上分配内存,避免额外复制(只要后续不手动释放,CFFI会自动管理内存)。 - 构建char[]指针数组*:用上述
char[]对象构建一个char*[]类型的cdata数组,作为char**参数传入C函数。 - 调用C函数并读取结果:传入数组后调用目标函数,最后通过
ffi.string读取处理后的字符串结果。
代码示例
import ffi # 假设已通过CFFI加载目标扩展,获取到lib和ffi对象 lib = ffi.dlopen("./libsort.so") # 替换为你的扩展库实际路径 # 待传递的字符串列表 str_list = ["banana", "apple", "cherry"] # 步骤1:编码每个字符串并创建C风格字符数组 c_strings = [ffi.new("char[]", s.encode("utf-8")) for s in str_list] # 步骤2:构建char*[]类型的指针数组 c_str_array = ffi.new("char*[]", c_strings) # 步骤3:调用C函数(假设sort_strings接收char**和数组长度两个参数) lib.sort_strings(c_str_array, len(str_list)) # 读取处理后的结果并转回Python字符串 processed_results = [ffi.string(c_str).decode("utf-8") for c_str in c_strings] print(processed_results)
关键说明
ffi.new("char[]", ...)创建的字符数组生命周期由CFFI自动管理,无需手动调用free(除非用ffi.gc手动接管内存)。- 此方案仅为每个字符串分配C风格内存并构建指针数组,无需复制整个列表,符合“优先无需复制列表”的需求。
内容的提问来源于stack exchange,提问作者MaxGyver
相关产品推荐
相关产品推荐

