c++ - 传递向量到 Lua 表
问题描述
我想通过发送一个 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 将取顶部索引,即表所在的索引。然后 lua_pushstring(L, ELEMENT); lua_rawseti(L, tbl, 计数器); 将 ELEMENT 放到我们使用 gettop 获得的索引 tbl 处的表中。元素的索引是计数器的值。
但是这里的问题是我不得不调用两次函数 GetCategory 来填充它,如下所示在我的 .lua 文件中。
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 Array[1][2] 中,然后推送 Array 失败
我对表、元表、多维数组等进行了大量研究,但找不到适合我需要或工作的东西。
有没有人有解决方案?
解决方案
你为什么不让你的函数返回两个值?然后你可以写
local Group = { GetCategories }
我不是 C API 方面的专家,但我认为这可以通过调用来相当容易地完成lua_newtable(L)
,所以像这样:
int GetCategories(lua_State* L) {
lua_settop(L, 0);
// Discard arguments so we don't have to save the top of the stack
// and can just use numbers instead (see following lines)
lua_newtable(L); // Index 1 on stack
lua_newtable(L); // Index 2 on stack
// Do your magic
lua_settop(L, 2); // Get rid of your temp variables
return 2; // number of values we return in 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) 将它们弹出:
// Modified for my suggested implementation that returns
// two tables. They can easily be turned around here.
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')
。
推荐阅读
- javafx - Maxsized屏幕中的Javafx AnchorPane始终位于左上角
- python - 如何使用 plt.loglog 在 matplotlib 中绘制一条斜率的线
- django - 如何获取生成错误的表单集表单的 ID?
- vb.net - 从 Listbox 中选择所有项目,通过 BackgroundWorker 将它们全部添加到 Listview
- error-correction - 为什么 RS(255,233) 有 32 个冗余符号?
- c# - C# 从机器人向频道电报发送消息
- c++ - 假设您有一个包含 N 个元素的数组。你需要找出有多少 i,Ai + A(i+1) 是一个平方数。这个问题是微不足道的吗?如果有怎么办?
- python - 如何有条件地从 Pandas 数据框中删除行
- android - 从 FirestorePagingOption 中排除文档
- vim - Vim 中 no{option} 和 inv{option} 有什么区别?