如何在C代码中获取lua_getglobal返回表的条目数与名称
在C代码中获取Lua表的条目数量与键名
你需要在C代码中获取lua_getglobal拿到的Lua表的条目数量及每个条目的名称,对应的MoonScript和C代码如下:
MoonScript代码:
Mytbl = { var = { active: true, ... }, inv = { active: true, ... }, sts = { active: true, ... }, ... }
对应的C代码(含占位符):
void read_test(void) { lua_State *L; L = luaL_newstate(); luaL_openlibs(L); if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)) { printf("Error 'test.lua'\n"); return; } lua_getglobal(L, "Mytbl"); for(int i = 1; i < GlobalEntry; i++) { lua_getfield(L, lua_gettop(L), get_tablename); lua_getfield(L, lua_gettop(L), "active"); p->active[i] = lua_toboolean(L, lua_gettop(L)); .... } lua_close(L); printf("Read complete.\n"); }
其中GlobalEntry是获取表条目数的占位,get_tablename是获取条目名称的占位,以下是具体实现方法:
实现方法
Lua提供了lua_next API来遍历表的所有键值对,同时可以通过遍历计数得到表的条目总数。因为你的表是字符串键的哈希表,不适合用lua_rawlen(仅适用于连续整数键的序列表),所以推荐用遍历的方式实现。
1. 遍历表获取键名与条目数
- 调用
lua_pushnil(L),将nil压入栈作为遍历的起始标记 - 循环调用
lua_next(L, -2):该函数会弹出栈顶的nil(或上一个键),将表的下一个键值对压入栈(键在栈顶-2位置,值在栈顶-1位置);若无更多键值对,返回0 - 每次遍历中,用
lua_tostring(L, -2)获取键的字符串名称,同时计数得到总条目数 - 处理完当前键值对后,调用
lua_pop(L, 1)弹出值,保持栈的状态(此时栈顶为当前键,方便下一次lua_next调用)
2. 修改后的完整C代码
#include <stdio.h> #include <lua.h> #include <lauxlib.h> #include <lualib.h> // 假设p是已定义的结构体指针 typedef struct { int active[10]; // 根据实际需求调整大小 } MyData; MyData *p; void read_test(void) { lua_State *L; L = luaL_newstate(); luaL_openlibs(L); if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)) { printf("Error 'test.lua'\n"); return; } lua_getglobal(L, "Mytbl"); // 检查栈顶是否为表 if (!lua_istable(L, -1)) { printf("Mytbl is not a table\n"); lua_close(L); return; } int entry_count = 0; int active_index = 0; lua_pushnil(L); // 初始化遍历 // 遍历Mytbl的所有键值对 while (lua_next(L, -2) != 0) { // 获取键名(当前栈:[-3]=Mytbl, [-2]=键, [-1]=值) const char *key_name = lua_tostring(L, -2); if (key_name != NULL && lua_istable(L, -1)) { // 进入子表,获取"active"字段 lua_getfield(L, -1, "active"); if (lua_isboolean(L, -1)) { p->active[active_index++] = lua_toboolean(L, -1); } lua_pop(L, 1); // 弹出active的值 entry_count++; } lua_pop(L, 1); // 弹出子表,回到键的位置 } printf("Total entries in Mytbl: %d\n", entry_count); lua_close(L); printf("Read complete.\n"); }
注意事项
- 遍历过程中不要修改被遍历的表,否则会导致遍历异常
- 每次调用
lua_next后,栈上会多一个键和一个值,处理完必须弹出值,保证栈状态正确 - 若需兼容序列表和哈希表,统一用
lua_next遍历计数是最可靠的方式
内容的提问来源于stack exchange,提问作者alberto silva
相关产品推荐
相关产品推荐

