在C/C++中使用C api读取lua表
假设lua表内容为
global = "g"
那么很容易我们可以使用获取全局变量的API
lua_getglobal
去获取全局变量的值
然而游戏中大部分情况下
配表文件中并没有全局变量
比如如下配表
local t = {a = "A" , b = "B"} return t
读取这样的配表
需要更加复杂的操作
包括如下几点
1.load文件后执行编译后的函数得到返回table
2.lua_next遍历table
3.处理table嵌套table的情况(二维数组)
1.load文件后执行编译后的函数得到返回table
int luaL_dofile (lua_State *L, const char *filename);
Loads and runs the given file. It is defined as the following macro:
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
It returns 0 if there are no errors or 1 in case of errors.
以上是最直接的方法
LUA_MULTRET宏值为-1
表示lua文件返回结果全部压栈
luaL_dofile从其定义我们可以看出,先加载后执行文件
以下则是具体的加载定义
int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname);
Loads a Lua chunk. If there are no errors, lua_load
pushes the compiled chunk as a Lua function on top of the stack. Otherwise, it pushes an error message.
This function only loads a chunk; it does not run it.
int luaL_loadfile (lua_State *L, const char *filename);
Loads a file as a Lua chunk. This function uses lua_load
to load the chunk in the file named filename
. If filename
is NULL
, then it loads from the standard input. The first line in the file is ignored if it starts with a #
.
This function returns the same results as lua_load
, but it has an extra error code LUA_ERRFILE
if it cannot open/read the file.
As lua_load
, this function only loads the chunk; it does not run it.
当luaFunction被push到栈顶之后,lua_pcall执行它就可以得到表(return值在栈顶)
lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
一般来说lua_pcall(state , 0--[[0个参数]] , 1--[[1个返回值]] , 0)即可
成功执行后return的table在栈顶
2.lua_next遍历table
int lua_next (lua_State *L, int index);
Pops a key from the stack, and pushes a key-value pair from the table at the given index (the "next" pair after the given key). If there are no more elements in the table, then lua_next
returns 0 (and pushes nothing).
/* table is in the stack at index 't' */ lua_pushnil(L); /* first key */ while (lua_next(L, t) != 0) { /* 'key' is at index -2 and 'value' at index -1 */ printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); /* removes 'value'; keeps 'key' for next iteration */ }
lua_next非常奇葩,完全是面向过程的
非常机械化的先pop栈顶元素,再或push一个keyValue-pair from table(if exist)
首先pushnil是为了防止首次lua_next时pop掉不该pop的东西
之后在循环内部手动pop一次,就可以保持循环(先pop1个,再push2个,再pop1个)
当循环结束时,栈顶元素不变
3.处理table嵌套table的情况(二维数组)
略(lua_type获得value的类型,如果类型是table则递归处理存储table中的值)
参考文献
http://manual.luaer.cn/
http://book.luaer.cn/
http://xxnull.blog.163.com/blog/static/176398157201181991147848/