在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/