1 堆栈相关
1.1
int (lua_gettop) (lua_State *L); 【-0,+0】
用于返回栈中元素的个数,同时也是栈顶元素的索引,因为栈底是1,所以栈中有多少个元素,栈顶索引就是多少;
2.2
void (lua_settop) (lua_State *L, int idx); 【-?,+?】
把栈索引idx设置为栈顶元素,这个可以删除栈的元素也可以扩充栈,idx可正可负.例如栈上有4个元素,lua_settop(L, 3)就是删除了1个元素,把栈底第3个元素(也是栈顶-2)作为栈顶,也可以表示为lua_settop(L, -2).我们可以得到一个关系--删除n个元素, 相当于把-n-1作为栈顶,lua中专门有一个宏:
#define lua_pop(L,n) lua_settop(L,-(n)-1)
2 全局相关
1.1
void (lua_setglobal) (lua_State *L, const char *name); 【-1,+0】
lua_setglobal:把栈顶的数据传到Lua环境中作为全局变量,并将该数据出栈,即栈高度-1.例如:
lua_pushinteger(L, 1235);
lua_pushstring(L, "abdg");
lua_pushstring(L, "xyz");
int n = lua_gettop(L); //n为3,即栈里有3个数据
lua_setglobal(L, "c");
int n = lua_gettop(L); //n为2,'xyz'出栈了
那么lua中就有一个全局变量c,值为c='xyz'
lua_pop(L, n);出栈n个数.其实lua_pop是个宏定义#define lua_pop(L,n) lua_settop(L, -(n)-1)
即让-n-1是栈顶(栈顶是-1,下面是-2....)
1.2
int (lua_getglobal) (lua_State *L, const char *name); 【-0,+1】
lua_getglobal:将lua中name变量入栈,栈高度+1.例如在lua中定义了一个函数myAdd,
functon myAdd(a, b) return a + b end
在c调用中lua_getglobal(L, "myAdd"),相当于将myAdd函数入栈,如果在lua中有一个全局变量a,lua_getglobal(L,"a"),相当于把a的值入栈,当然入栈可以用lua_pushinteger(L,2).调用就是lua_pcall(L,2, 0,0)第二个参数是入参的个数,第三个是返回的个数.此时栈上第三个值必须是要执行的函数
执行lua_pcall(L,n,r,0)的过程是,将栈顶的前n个数依次出栈,作为函数的参数,然后栈顶就是函数了,执行后,将返回值反向入栈,r大于函数返回数量的个数,就压入nil,小于的话就忽略多余的返回值
3 表相关
2.1 取表的元素入栈
void lua_gettable (lua_State *L, int index) 【-1,+1】
他的作用是取栈[index]表的元素,元素索引为栈顶的值,然后将栈顶值弹出,表的key对应的val值入栈,伪代码就是:
ele = Stack[index]
key = Stack.top()
Stack.pop()
value = ele[key]
Stack.push(value)
根据index指定取到相应的表; 取栈顶元素为key, 并弹出栈; 获取表中key的值压入栈顶.
无返回值
栈高度不变, 但是发生了一次弹出和压入的操作, 弹出的是key, 压入的是value
注意, 该操作将触发 __index 元方法
2.2 修改表的元素
void lua_settable (lua_State *L, int index) 【-2,+0】
操作: ele = Stack[index]
value = Stack.top()
Stack.pop()
key = Stack.top()
Stack.pop()
ele[key] = value
根据index指定取到相应的表; 取栈顶元素做value, 弹出之; 再取当前栈顶元素做key, 亦弹出之; 然后将表的键为key的元素赋值为value
无返回值,栈高度-2,,第一次弹出value,第二次弹出key,例如
lua_pushstring(L, "key");
lua_pushstring(L, "val");
lua_settable(L, LUA_REGISTRYINDEX);
lua_getfield(L, LUA_REGISTRYINDEX, "key"); 现在栈顶为'val'
注意, 该操作将触发 __newindex 元方法
2.3 取表的元素入栈
我们注意到上面的表操作,其索引值(k)都是取栈顶元素,其实还可以直接指定k,不过k必须是字符串了
int lua_getfield (lua_State *L, int index, const char *k) 【-0,+1】
操作: tab = Stack[index] // tab肯定是表
Stack.push( tab[k] )
取表中键为k的元素, 这里的表是由index指向的栈上的一个表
返回压入值得类型
栈高度+1, 栈顶元素是(Stack[index])[k]
注意, 该操作将触发 __index 元方法
例子:
function func ({a = 123}) end
在执行func的时候lua_getfield(L, 1, 'a')就把123压入到栈顶
与上面类似的函数是:
int lua_geti (lua_State *L, int idx, lua_Integer n) 【-0,+1】
操作: tab = Stack[index] // tab肯定是表
Stack.push( tab[n] )
取表中键为n的元素, 这里的表是由index指向的栈上的一个表
返回压入值得类型
栈高度+1, 栈顶元素是(Stack[index])[k]
注意, 该操作将触发 __index 元方法
例子:
function func ({a = {11,22}}) end
在执行func的时候lua_getfield(L, 1, 'a')就把a压入到栈顶,栈顶变为2,然后lua_geti(L, 2, 1)就是从栈2的地方获取表a[1]
2.4 修改表的元素
void lua_setfield (lua_State *L, int index, const char *k) 【-1,+0】
操作: tab = Stack[index]
tab[k] = Stack.top()
Stack.pop()
给表中键为k的元素赋值value(value就是栈顶元素), 这里的表是由index指向的栈上的一个表
无返回值
栈高度-1, 被弹出的是value
注意, 该操作将触发 __newindex 元方法
void lua_rawseti (lua_State *L, int index, lua_Integer i) 【-1, +0】
Does the equivalent of t[i] = v, where t is the table at the given index and v is the value at the top of the stack. This function pops the value from the stack. The assignment is raw, that is, it does not invoke the __newindex metamethod.
4 函数相关
void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n) 【-n,+1】
压入一个函数到栈顶.
比如我要在lua中执行一个c函数,可以用lua_pushcclosure压入c本地函数到栈顶,然后给该函数命名为lua中要执行的函数名(调用lua_setglobal(L, "funName")),这样lua代码就能执行c的函数了.其实有这个过程的宏定义了:lua_register(L, f, funName)
我们注意到lua_pushcclosure函数还有一个参数n,他的含义是upvalue的个数.upvalue简单的理解就是要给这个函数设置这个函数作用域可见的变量.
比如,我在给栈顶压入一个函数时,先压入一个upvalue,这样在函数调用中就能取到那个upvalue了:
lua_pushinteger(L, 100); //压入一个upvalue 100
lua_pushcclosure(L, myAdd, 1); //压入函数,并带一个upvalue值,从栈顶取,即上面的100
lua_setglobal(L, "myAdd");
lua代码 myAdd(3,5)
static int myAdd(lua_State* L)
{
int k = lua_tonumber(L, lua_upvalueindex(1)); --对应upvalue 100
int n = lua_gettop(L);
double op1 = luaL_checknumber(L, 1);
double op2 = luaL_checknumber(L, 2);
lua_pushnumber(L, op1 - op2);
n = lua_gettop(L);
return 2;
}
类似的还有:
void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 【-nup,+0】
注册函数数组l到栈顶的表里面。
有关闭包,upvalue请参考下一篇:
参考:
https://www.cnblogs.com/ringofthec/archive/2010/10/22/lua.html
http://blog.youkuaiyun.com/yuliying/article/details/43412355