lua知识点整理
1. lua全局环境和局部环境
local cf = loadstring(" local i=0 i=i+1 print(i) ") --从后面两个输出我们可以看出,生成的函数的环境就是全局_G print(cf,getfenv(cf),_G) -- function: 0058AAB0 table: 00582ED8 table: 00582ED --改变_G的值 _G = {} cf() -- 1 --虽然改变了_G的值,但函数的的环境仍然是全局环境table,地址仍然是0058AAB0 print(cf,getfenv(cf),_G) -- function: 0058AAB0 table: 00582ED8 table: 0058BFF0 -- function: 0058AAB0 table: 00582ED8 table: 00582ED8 -- 1 -- function: 0058AAB0 table: 00582ED8 table: 0058BFF0 -- [Finished in 0.1s]
-- -- 用局部变量list模拟_G(用list表的元素_A保存list表自身,为什么这样做??) -- local list = {_A = "ddddd", _B = "bbbbb", _C = "ccccc",} -- list._A = list -- -- print(list) -- -- print(list._A) -- -- print(list._A._A) -- 类似:_G._G = _G -- for k, v in pairs(list) do -- -- print(k, "=", v, type(v)) -- end ------------------------------------------------------- -- 搜索:局部变量 -> 全局变量 -> 环境 -- 用局部变量 _A 模拟_G(用list表的元素_A保存list表自身,为什么这样做??) local _A = {_A = "ddddd", _B = "bbbbb", _C = "ccccc",} _A._A = _A print(_A) print(_A._A) -- 类似:_G._G = _G print(_A._A._A) for k, v in pairs(_A) do print(k, "=", v, type(v)) end -- output -- -- table: 004FBFF0 -- table: 004FBFF0 -- table: 004FBFF0 -- _A = table: 004FBFF0 table -- _C = ccccc string -- _B = bbbbb string -- [Finished in 0.1s]
[参见]
http://blog.sina.com.cn/s/blog_4458fdda01012f4b.html
http://www.tuicool.com/articles/RVZvMbn
http://blog.csdn.net/maximuszhou/article/details/24105673?utm_source=tuicool
http://blog.csdn.net/ball32109/article/details/11402727
http://blog.codingnow.com/2011/12/lua_52_env.html
http://www.cnblogs.com/ringofthec/archive/2010/11/09/lua_State.html
--------------------------------------------------------------------------------------------------
2. C中遍历lua表结构
// 进行下面步骤前先将 table 压入栈顶 int nIndex = lua_gettop( pLua ); // 取 table 索引值 lua_pushnil( pLua ); // nil 入栈作为初始 key while( 0 != lua_next( pLua, nIndex ) ) { // 现在栈顶(-1)是 value,-2 位置是对应的 key // 这里可以判断 key 是什么并且对 value 进行各种处理 lua_pop( pLua, 1 ); // 弹出 value,让 key 留在栈顶 } // 现在栈顶是 table
lua_next() 这个函数的工作过程是:
1) 先从栈顶弹出一个 key(这也是为什么需要首先压入一个nil (lua_pushnil(pLua)) ) .
2) 从栈指定位置的 table 里取下一对 key-value,先将 key 入栈再将 value 入栈
3) 如果第 2 步成功则返回非 0 值,否则返回 0,并且不向栈中压入任何值
第 2 步中从 table 里取出所谓“下一对 key-value”是相对于第 1 步中弹出的 key 的。table 里第一对 key-value 的前面没有数据,所以先用 lua_pushnil() 压入一个 nil 充当初始 key。
注意:
开始的时候先用 lua_gettop() 取了一下 table 在栈中的正索引(前面说过了,在进行这个 lua_next() 过程之前先将 table 入栈,所以栈大小就是 table 的正索引),后面的 lua_next() 过程中不断的有元素出入栈,所以使用正索引来定位 table 比较方便。
到了 table 中已经没有 key-value 对时,lua_next() 先弹出最后一个 key,然后发现已经没有数据了会返回 0,while 循环结束。所以这个 lua_next() 过程结束以后 table 就又位于栈顶了。
问题概要: 用lua写了个函数,返回的是一个表.需要在C里对返回的表里元素做二次处理. 在C里我们可以通过lua_gettable()或者lua_rawget()来获取表里元素值,但使用这两个接口的前提是你得知道key,它才能给你 value. 当然对于顺序下标倒无所谓,但恰巧这次我用到的是关联数组,下标是无规则字符串.这时候如何遍历出表里元素就是个问题. lua_next()就成了比较合适的选择.
上图对简单的表遍历做了介绍, 但事实上的情况是我返回了一个二维表,如果你了解了lua_next()的处理过程,那下面的代码看起来就没什么问题了.
t_idx = lua_gettop(L); lua_pushnil(L); while (lua_next(L, t_idx)) { printf("============================\n"); it_idx = lua_gettop(L); lua_pushnil(L); while(lua_next(L, it_idx)) { printf("%s\n", lua_tostring(L, -1)); lua_pop(L, 1); } lua_pop(L, 1); }