在lua中有几个关键点必须搞清楚,这个都是需要仔细去揣摩的。
一。堆栈调用
lua和其他语言交互是通过堆栈来操作,那么那些明明了了的调用就变成在堆栈上push和pop上做文章了。
比如你要取一个lua文件中的某个数值,不是一个等号就能得到,而是调用lua_getglobal()把lua中数值变量压入堆栈,然后通过lua_tostring或者lua_tonumber来获取它。如果这还可以理解的话,那么把lua文件中表的处理,则需要一系列的压栈和处理索引后才能获取。如果参数很多,还要注意索引值的正确与否。
二表之堆栈调用
看手册时,发现这点非常不易理解。而且手册的帮助也是看得人琢磨不透。以下说明
void lua_settable (lua_State *L, int index);
等价 t[k] = v
操作,这里 t
理解为table,为index
索引所对应的表, v
为值, k
键名。
实际上就是对表操作,再说白些,就是在堆上处理某个表的修改。其完整的操作都是先需要
lua_pushxxx后,对某个表做t[k]=v操作。完事后,该函数弹出-2,-1处值
英文:
void lua_settable (lua_State *L, int index);
Does the equivalent to t[k] = v
, where
t
is the value at the given valid index index
,
v
is the value at the top of the stack, and k
is the
value just below the top.
This function pops both the key and the value from the
stack. As in Lua, this function may trigger a metamethod for the "newindex"
event
其实画个图,就是这个样
索引号 表
堆栈 堆栈相对位置
index ----> t
------->v(值)
-1
k (键名) -2
该操作其实对 表t[k]=v
void lua_gettable (lua_State *L, int index);
把t[k]
值压入堆栈,通过lua_toxxxx取出该值。
index
指向某个表,而 k
则为某个表的键名。调用该函数时,需要先压入一个k,表(索引)键名。
调用该函数,其实就是在堆中把t[k]的值获取处理,完事后弹出k,而返回的表值在堆的顶部(-1处)。
拿个例子来讲最生动:
比如调用一个函数,其中函数是在lua中定义的表中的函数,即:
mytable = {
Function1 = function (var ) return var.."world,my
test" end
}
。。。
lua_pushstring(L,
"mytable");
--压表名,将在全局栈中找该表
lua_gettable(L,
LUA_GLOBALSINDEX); --以表名查表在全局表中的位置,结果在堆顶
lua_pushstring(L,
"Function1");
--压函数名,“Function1”在堆栈-1处,
mytable的表索引在-2位置(不是字符串)
lua_gettable(L,
-2);
--在mytable表中查找function1的索引值(指针),
该操作完后,栈顶为function1函数指针。
lua_pushstring("hello");
--压参
lua_pcall(L, 1, 1, 0); --调用函数,返回一个参数。
lua_String msg = lua_tostring(L,
-1);
lua_pop(L, 1);
四 垃圾收集
这个概念是这样的:
lua不需要用户干预内存的操作,只是通过垃圾收集器来自动管理内存。所有对象都被自动管理,有: table, userdata、 函数、线程、和字符串。
其管理机制是:通过递增的标志来决定是否收集,用2个标记数字来控制垃圾收集周期:
garbage-collector
pause 和 garbage-collector step multiplier 。
collector pause 按收集周期决定收集内存,当其数值越大,则收集周期也越长。
step
multiplier 按相对内存分配的速度来收集。数值越大收集器则收集更快。