lua 和C交互相关函数

18 篇文章 16 订阅

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请参考下一篇:

lua upvalue

 

参考:

https://www.cnblogs.com/ringofthec/archive/2010/10/22/lua.html

http://blog.csdn.net/yuliying/article/details/43412355

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值