传递一个 Vector<struct> 到 Lua 表中
2018-8-23 12:8:21
收藏:0
阅读:116
评论:2
我想通过发送一个 C++ 预格式化的 Lua 表来改进我的下面的代码:
int GetCategory(lua_State* L)
{
uint32 Type = CHECKVAL<int>(L, 1);
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 counter = 1;
// Struct CT { string CategoryBrandName, CategoryName }; > Vector<CT>
auto list = sManagerMgr->GetAll();
// Hack modify this to send a metatable/UserData/Table whatever is called
for (auto& elem : list)
{
switch (Type)
{
case 1:
lua_pushstring(L, elem->CategoryBrandName);
break;
case 2:
lua_pushstring(L, elem->CategoryName);
break;
}
lua_rawseti(L, tbl, counter);
counter++;
}
lua_settop(L, tbl);
return 1;
}
基本上, lua_newtable 将一个表推送到 Lua 栈中, lua_gettop 将取出顶部索引,因此我们在得到的 tbl 索引处放置表。 然后 lua_pushstring(L, ELEMENT); lua_rawseti(L, tbl, counter); 将 ELEMENT 放入索引为 tbl 的表中。元素的索引是计数器的值。
但问题在于,我被迫调用 GetCategory 函数两次才能填充它,如下所示:
table.insert(Group, { GetCategory(1), GetCategory(2) });
当前用法:
print(i, Group(1)[i], Group(2)[i]);
所以…我更愿意调用它一次并直接获得以下内容:
local Group =
{
[1] = { "elem->CategoryBrandName[1]", "elem->CategoryName[1]" },
[2] = { "elem->CategoryBrandName[2]", "elem->CategoryName[2]" }
//etc
};
我尝试将 elem 填充到一个 2D 数组 [1][2] 中,然后不成功地将其推入数组中
我对表、元表、多维数组等进行了大量的研究,但找不到适合我的需要或可行的东西。
有人有解决办法吗?
点赞
用户7270457
如果有人正在寻找类似的东西,这里是我使用lua_createtable的方式。它可以按预期工作,但可能需要一些改进。
int GetCategory(lua_State* L)
{
int counter = 1;
int MaxListSize = 2;
auto Categories = sManagerMgr->GetAll();
lua_createtable(L, Categories.size(), 0);
for (auto& elem : Categories)
{
vector<string> list;
list.reserve(MaxListSize);
list.emplace_back(elem->CategoryBrandName);
list.emplace_back(elem->CategoryName);
Macro::Push(L, counter); // custom
lua_createtable(L, 0, MaxListSize);
for (int i = 1; i <= MaxListSize; i++)
{
Macro::Push(L, list.at(i - 1)); // custom
lua_rawseti(L, -2, i);
}
lua_settable(L, -3);
list.clear();
counter++;
}
return 1;
}
将会产生类似以下的输出
local Group =
{
[1] = { "elem->CategoryBrandName[1]", "elem->CategoryName[2]" },
[2] = { "elem->CategoryBrandName[1]", "elem->CategoryName[2]" }
--等等
};
2018-08-28 16:11:03
评论区的留言会收到邮件通知哦~
推荐文章
- 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 代码?

为什么不让函数返回两个值呢?那样你就可以这么写:
local Group = { GetCategories }我不是 C API 的专家,但我认为这可以通过调用
lua_newtable(L)来轻松实现,就像这样:int GetCategories(lua_State* L) { lua_settop(L, 0); // 抛弃参数,这样我们就不必保存栈顶, // 可以直接使用数字(见下面的代码) lua_newtable(L); // 栈顶索引为 1 lua_newtable(L); // 栈顶索引为 2 // 干你的事情 lua_settop(L, 2); // 清除你的临时变量 return 2; // 我们在 Lua 中返回的值的数量 }优化提示:你可以使用
lua_createtable并告诉它每个表将有多少个元素,这样 Lua 就可以为其预分配一些内存。编辑:我刚刚注意到你的代码中:
for (auto& elem : list) { switch (Type) { case 1: lua_pushstring(L, elem->CategoryBrandName); break; case 2: lua_pushstring(L, elem->CategoryName); break; } lua_rawseti(L, tbl, counter); counter++; }你不断地往堆栈里推值。对于长向量,它可能很快就会导致堆栈溢出,从而带来麻烦。更好的方法是:1)推到堆栈,2)插入到表中,3)把它们弹出来:
// 修改为我建议的返回两个表的实现方式。 // 这里它们可以很容易地相互转换。 for (auto& elem : list) { lua_pushstring(L, elem->CategoryBrandName); lua_rawseti(L, 1, counter++); lua_pop(L, 1); lua_pushstring(L, elem->CategoryName); lua_rawseti(L, 2, counter++); lua_pop(L, 1); }时刻牢记哪些东西在堆栈上是个好主意。节省一些内存不仅可以提高性能,还可以避免由于(Lua)堆栈溢出而带来的潜在问题。
最后一个细节:Lua 中不需要
;,除非你在同一行中有两个语句print('more readable'); print('like this'),否则使用它们被认为是一种不好的风格。