基于Ubuntu 21.10系统与Lua 5.4.3(使用cffi-lua而非LuaJIT/FFI),如何实现Lua数组表与C函数dummy的双向传递?
在cffi-lua中实现Lua表与C整数数组的双向传递
嘿,我来帮你搞定用cffi-lua在Lua和C之间传递整数数组的问题~ 下面分两个场景详细说明:
1. 将Lua表传递给C函数
cffi-lua没法直接把Lua表传给C的指针参数,咱们需要先把Lua表的内容转换成C风格的int数组,再传递给C函数。具体步骤如下:
-- 你的原始定义 local ffi = require("cffi") ffi.cdef [[ void dummy(int* ptr_from_lua, int size) ]] local mytable = {2,4,6,8} -- 模拟整数数组的Lua表 local size = #mytable -- 1. 创建一个C类型的int数组,大小和Lua表一致 -- 这里用`ffi.new("int[?]", size)`的语法,`?`表示动态指定数组大小 local c_int_array = ffi.new("int[?]", size) -- 2. 把Lua表的元素复制到C数组中 -- 注意:Lua表是1索引,而C数组是0索引,所以要做索引转换 for i = 1, size do c_int_array[i-1] = mytable[i] end -- 3. 调用C函数,传递C数组指针和数组大小 ffi.C.dummy(c_int_array, size) -- 小贴士:用`ffi.new`创建的C数组会被Lua的垃圾回收自动处理,不用手动释放; -- 但如果是用`ffi.C.malloc`手动分配的内存,记得用`ffi.C.free`释放,或者用`ffi.gc`绑定回收逻辑
2. 从C函数传递数据回Lua表
如果你的C函数会修改传入的数组内容,或者返回一个新的整数数组,咱们可以把C数组的内容复制回Lua表:
场景A:C函数修改了传入的数组
假设C函数dummy修改了ptr_from_lua指向的数组内容,调用完成后咱们可以把修改后的数据同步回Lua表:
-- 接上面的代码,调用完C函数后执行: for i = 1, size do mytable[i] = c_int_array[i-1] end -- 此时mytable已经是C函数修改后的内容了 print(table.concat(mytable, ", "))
场景B:C函数返回一个新分配的数组
如果C函数是动态分配内存并返回数组指针(比如int* create_new_array(int size)),咱们需要注意内存管理,避免内存泄漏:
-- 先定义C函数 ffi.cdef [[ int* create_new_array(int size); void free(void* ptr); ]] local new_size = 5 -- 调用C函数获取新数组指针 local new_c_array = ffi.C.create_new_array(new_size) -- 绑定垃圾回收逻辑,让Lua自动释放内存 ffi.gc(new_c_array, ffi.C.free) -- 把C数组内容复制到新的Lua表 local new_lua_table = {} for i = 0, new_size - 1 do table.insert(new_lua_table, new_c_array[i]) end -- 现在new_lua_table就包含了C函数返回的数组内容
关键注意点
- 索引转换:Lua表默认是1索引,而C数组是0索引,一定要注意循环时的索引对应关系,不然会出现数据错位或者越界问题。
- 内存管理:用
ffi.new创建的C内存会被Lua GC自动回收,但手动用malloc分配的内存必须手动释放,或者用ffi.gc绑定回收函数。 - 类型匹配:确保Lua表中的元素都是整数,避免传递浮点数导致C函数处理出错(cffi-lua会自动把Lua number转成int,但非整数会被截断)。
内容的提问来源于stack exchange,提问作者jradxl
相关产品推荐
相关产品推荐

