如何用SWIG封装返回可变float数组的C函数为Lua表?
用SWIG封装动态长度float数组并返回为Lua表的实现方案
我之前已经成功搞定了固定长度float数组的SWIG封装,Lua里直接就能拿到对应的表,现在又遇到了动态长度数组的需求,折腾了一番后终于搞定了,分享下我的实现过程:
先回顾下固定长度的实现
之前的C函数是这样的:
static void getArray(int size, float values[4]) { for (int i=0; i<size; ++i) values[i] = (float)i; }
对应的SWIG接口里用现成的类型映射就搞定了:
%include <typemaps.i> %apply (float OUTPUT[ANY]) {(float values[4])};
Lua里调用arr = my.getArray(4)直接拿到{0,1,2,3},非常顺畅。
动态长度数组的挑战与解决
现在要封装的是返回可变长度数组的C函数,原型是:
static void getArray(int size, float **values) { // 要在这里创建动态数组,最终转成Lua表返回 }
结合我用到的t_word结构体(里面有w_float的float字段,而且这块内存不用手动释放),我写了对应的SWIG类型映射,完美实现了需求。
第一步:完善C函数的逻辑
先把动态创建数组的代码写好:
#include <stdlib.h> // 我的场景里用到的t_word结构体,供参考 typedef struct { float w_float; } t_word; static void getArray(int size, float **values) { // 动态分配对应大小的float数组 *values = (float*)malloc(size * sizeof(float)); if (!*values) return; // 内存分配失败直接返回 // 填充数组数据,这里用t_word的w_float字段做示例 for (int i = 0; i < size; ++i) { t_word temp_word; temp_word.w_float = (float)i * 1.2f; // 随便填的示例数据 (*values)[i] = temp_word.w_float; } }
第二步:编写SWIG的自定义类型映射
在SWIG的.i文件里,需要自定义类型映射来处理float**这个输出参数,把它转成Lua表:
%module my %{ #include "your_code.h" // 引入你的C函数和t_word的头文件 %} // 自定义out类型映射,把float**转成Lua表 %typemap(out) float** { if ($1 && *$1) { // 创建一个新的Lua表 lua_newtable(L); int arr_size = $input; // 这里取函数的第一个参数size,注意参数位置要对应 for (int i = 0; i < arr_size; ++i) { lua_pushnumber(L, (*$1)[i]); lua_rawseti(L, -2, i+1); // Lua表的索引是从1开始的 } // 因为我的场景里t_word相关内存不用手动释放,这里就不用free了 $result = lua_gettop(L); } else { // 数组为空的话返回nil lua_pushnil(L); $result = lua_gettop(L); } } // 调整参数的argout映射,配合out映射完成处理 %typemap(argout) float** { // 这里可以根据需求补充额外逻辑,比如清理临时变量等 } // 把C函数暴露给Lua void getArray(int size, float **values);
第三步:Lua里的调用效果
现在在Lua里直接调用就可以拿到动态生成的表了:
local dynamic_arr = my.getArray(6) -- 得到的表是{0.0, 1.2, 2.4, 3.6, 4.8, 6.0}
一些关键注意点
- 类型映射里的
$input是指函数的第一个参数,如果你size不是第一个参数,要调整成对应的$input1、$input2这种格式。 - 如果你的场景里是普通malloc的数组,需要考虑内存回收,可以用SWIG的
%newobject或者自定义Lua的清理函数来避免内存泄漏。 - 我的场景里
t_word的内存不需要手动释放,所以省了free的步骤,大家要根据自己的内存管理逻辑调整。
内容的提问来源于stack exchange,提问作者Zack Lee
相关产品推荐
相关产品推荐

