创建 SWIG 的类型映射,使得 C 函数可以返回 Lua 表
2018-6-5 11:37:35
收藏:0
阅读:94
评论:1
我正在尝试包装一个创建浮点数组并将其作为 Lua 表返回以便在 Lua 中使用的 C 函数。
以下是返回具有 4 个元素的浮点数组的 C 函数。
static void getArray(int size, float values[4]) {
for (int i=0; i<size; ++i)
values[i] = (float)i;
}
这是在 .i 文件中的类型映射部分。
// 使用类型映射
%include <typemaps.i>
%apply (float OUTPUT[ANY]) {(float values[4])};
在 Lua 中,我可以使用以下方式使用该函数:
arr = my.getArray(4); //表"arr"现在为{0,1,2,3}
虽然这很好用,但我想知道是否可能创建一个可以返回可变浮点数组的 C 函数。
因此,我认为该函数将类似于以下内容。
static void getArray(int size, float **values) {
//创建一个浮点数组,然后将其返回为 Lua 中的表。
}
但是,我不知道如何使用 SWIG 接口 (.i) 绑定此函数。
我尽我所能尝试了一切,但到目前为止都没能成功。
请问有谁可以指导我如何使用 SWIG 包装此函数以便我可以返回 Lua 中的可变浮点数组作为表?
P.S:这是 Lua SWIG 文档的链接。 http://www.swig.org/Doc1.3/Lua.html
------------------------以下是补充内容------------------------
@Flexo 基于您的更新解决方案,我成功地绑定了以下 getArray 函数。
static void getArray(const string &name, int *size, t_word **values) {
t_garray *a;
int vecsize;
t_word *vec;
if (getArrayData(name, &a, &vecsize, &vec)) {
*values = vec;
*size = vecsize;
}
}
这是我的 SWIG 接口。
%typemap(in,numinputs=0) (int *size, t_word **values) (t_word *tmp=NULL, int tsize=0) %{
$2 = &tmp; // 使用我们设置的临时变量
$1 = &tsize;
%}
%typemap(argout) (int *size, t_word **values) {
int i;
lua_newtable(L);
for (i = 0; i < *$1; i++){
lua_pushnumber(L,(lua_Number)(*$2)[i].w_float);
lua_rawseti(L,-2,i+1);/* -1 代表数字,-2 代表表*/
}
SWIG_arg++;
}
t_word 是用于包含浮点数据 w_float 的数组的结构体。
由于我没有分配新的内存,因此我不需要释放任何内容,它似乎运行得非常好。
非常感谢您的帮助。我从您的代码中学到了很多。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

使用多参数类型映射可以完成此操作。我基于typemaps.i中的OUTPUT [ANY]的类型映射,编写了一个快速测试以展示如何工作:
%typemap(in,numinputs=1) (int size, float **values) (float *tmp=NULL) %{ $2 =&tmp; //使用我们设置的临时变量 //以下两行等同 //$1 =(int)lua_tonumber(L,$input); $typemap(in,int); %} %typemap(freearg)(int size, float **values) %{ free(tmp$argnum); //假定这里是正确的语义 %} %typemap(argout)(int size, float **values) { //从typemaps.i中的OUTPUT [ANY] argout复制而来 int i; lua_newtable(L); for (i = 0; i < $1; i++){ lua_pushnumber(L,(lua_Number)(*$2)[i]); lua_rawseti(L,-2,i+1);// -1是数字,-2是表* / } SWIG_arg++; } %inline %{ static void getArray(int size, float **values) { //创建一个浮点数组,然后将其作为Lua中的表返回。 float *arr = malloc(sizeof *arr * size); for (int i = 0; i < size; ++i) { arr[i] = i; } *values = arr; }从Lua中,我们可以像这样使用这个函数:
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio > l=require('test') > l table: 0xcb87de8 > l.getArray() stdin:1: Error in getArray expected 1..1 args, got 0 stack traceback: [C]: in function 'test.getArray' stdin:1: in main chunk [C]: in ? > l.getArray(1) table: 0xcb86d48 > l.getArray(1) table: 0xcb88b50 > l.getArray(1)[0] nil > l.getArray(1)[1] 0.0 > l.getArray(1)[2] nil > l.getArray(3)[2] 1.0 > l.getArray(3)[3] 2.0 > l.getArray(3)[4] nil在这里大部分工作都是在argout类型映射中完成的,它创建一个新表并用我们的
getArray()函数放入float **输出参数中的值进行填充。如果实际的
getArray()版本实际上没有让您指定或找出输出的长度,那么最好根本不对其进行包装,而是专注于包装getArrayData()本身。(如果需要,您可以使用%rename让接口感觉对于已经熟悉C ++ API的用户更为相似)。对于包装getArrayData(),我会更改它,例如:%module test %include <std_string.i> %typemap(in,numinputs=0) (int *size, float **values) (float *tmp=NULL,int tsize=0) %{ $2 =&tmp; $1 =&tsize; %} %typemap(argout)(int *size, float **values) { //从typemaps.i中的OUTPUT [ANY] argout复制而来 int i; lua_newtable(L); for (i = 0; i < *$1; i++){ lua_pushnumber(L,(lua_Number)(*$2)[i]); lua_rawseti(L,-2,i+1);// -1是数字,-2是表* / } SWIG_arg++; } %inline %{ static void getArrayData(const std::string& name, void *something_else, int *size, float **values) { //假装有人已经拥有了这个内存 static float arr[100]; *size = sizeof arr / sizeof *arr; for (int i = 0; i <*size; ++i) { arr[i] = i; } *values = arr; } %}关键更改:
-类型映射内的额外本地变量,用于size输出