Lua常用API
2015-05-26 12:11
337 查看
转自:http://www.cnblogs.com/ringofthec/archive/2010/10/22/lua.html
1.建一个新表
操作:ele=Stack[index]
key=Stack.top()
Stack.pop()
value=ele[key]
Stack.push(value)
根据index指定取到相应的表;取栈顶元素为key,并弹出栈;获取表中key的值压入栈顶.
无返回值
栈高度不变,但是发生了一次弹出和压入的操作,弹出的是key,压入的是value
注意,该操作将触发__index元方法
和lua_gettable操作一样
但是不触发相应的元方法
voidlua_rawgeti(lua_State*L,intindex,intn)
操作:ele=Stack[index]
value=ele
Stack.push(value)
无返回值
栈+1,栈顶新增元素就是value
不触发相应的元方法
和lua_settable操作一样
但是不触发相应的原方法
操作:ele=Stack[index]
value=Stack.top()
Stack.pop()
ele
=value
无返回值
栈-1,栈顶将value弹出
不触发相应的元方法
6.复制栈上元素并压入栈
操作:value=Stack[index]
Stack.push(value)
无返回值
栈+1
7.创建一个元表
操作:1.在注册表中查找tname,如果已经注册,就返回0,否者继续,并平栈
lua_getfield(L,LUA_REGISTRYINDEX,tname)
if(!lua_isnil(L,-1))
return0;
lua_pop(L,1);
2.创建一个表,并注册,返回1
lua_newtable(L)
lua_pushvalue(L,-1)
lua_setfield(L,LUA_REGISTRYINDEX,tname)
return1
该函数分配一块由size指定大小的内存块,并放在栈顶
返回值是新分配的块的地址
栈+1,栈顶是userdata
userdata用来在lua中表示c中的值.一个完整的userdata有自己的元表,在垃圾回收时,可以调用它的元表的__gc方法
9.注册c函数到lua中,其实没有这回事,lua中只有c闭包
向栈上压一个C闭包
当一个c函数被创建时,可以绑定几个值在它上面,从而形成一个闭包.在任何时刻调用这个c函数时,都可以访问这几个绑定值.
绑定的方法:先一次压入要绑定的n个值到栈上,然后调用lua_pushcclosure(L,fn,n)这样就形成的一个c闭包
无返回值
栈–(n-1),一共弹出n个元素(及那些绑定的值),压入一个cclosure
#definelua_pushcfunction(L,f)lua_pushcclosure(L,f,0)
#definelua_register(L,n,f)(lua_pushcfunction(L,f),lua_setglobal(L,n))
没有返回值
栈不变化
这个是比较常用的,以n为lua中的key压入一个0个绑定值的cclosure.
10.调用一个lua函数
voidlua_call(lua_State*L,intnargs,intnresults)
luacapi的特点就是"不是一个人在战斗"[我想表达的意思是,lua中的一句话,在capi实现起来就是n句,可能有人疑惑那为什么不直接用lua多好,capi这么麻烦,答案是有的事只能用capi才能实现],所以,调用它之前,需要布局一下栈,第一,要把要call的函数压入栈;第二,call要用的参数正序压入栈中;然后才能调用lua_call,调用完了,自己去取返回值,它都给你压栈上了.
操作:
无返回值
调用结束后,栈高度增加nresults–(1+nargs),如果将nresults参数设置为LUA_MULTRET,那么lua返回几个值,栈上就压入几个值,否者强制压入nresults个值,不足的是空值,多余的抛弃掉
注意,这个函数是有危险的,如果在其中发生了错误,会直接退出程序
这个函数的用途:尚未发现,除非你能接受出错立马退出,反正我是做游戏的,我受不起,呵呵,顺便一说,lauxlib.h中的luaL_check*一族函数也是这样的,不符合预期的话,直接退出,这些函数都要小心,有类似于断言的效果.
11.保护下调用一个lua函数
intlua_pcall(lua_State*L,intnargs,intnresults,interrfunc)
参数,行为和lua_call都一样,如果在调用中没有发生任何错误,lua_pcall==lua_call;但是如果有错误发生时,lua_pcall会捕获它
errfunc指出了Stack上的一个元素,这个元素应该是一个函数,当发生错误的时候
ef=Stack[errfunc]
value=ef(errmsg)
Stack.push(value)
也就是说,在错误的时候,errfunc指定的错误处理函数会被调用,该处理函数的返回值被压到栈上.
默认情况下,可以给errfunc传值0,实际的效果是指定了这样一个函数做出错处理functiondefaulterr(errmsg)returnerrmsgend.
本函数有返回值LUA_ERRRUN运行时错误LUA_ERRMEM内存分配错误[注意,这种错会导致lua调用不了错误处理函数]LUA_ERRERR运行错误处理函数时出错了,写程序的时候必须检查返回值:)
强烈推荐该函数,不过事实上大家也都用的这个函数:)
12.保护下调用一个c函数
以保护模式调用c函数,func中可以且只能从堆栈上拿到一个参数,就是ud,当有错误时,和lua_pcall返回相同的错误代码,并在堆栈顶部留下errmsg字符串,调用成功的话它返回零,并且不会修改堆栈,所有从func中返回的值都被扔掉.
这里注意的问题是:
1."当有错误时",这个错误的意思是lua的错误,而不是c/c++的错误.在func中使用lua_call和lua_check*族函数,并不会导致程序退出了,而是表现的像lua_pcall那样.
2.调用成功的时候func中的返回值都被扔掉了.
1.建一个新表
voidlua_createtable(lua_State*L,intnarr,intnrec)
创建一个新的table,并把它放在栈顶.narr和nrec分别指定该table的array部分和hash部分的预分配元素数量
无返回值
栈高度+1,栈顶元素是新table
#definelua_newtable(L)lua_createtable(L,0,0)常用这个
2.取表中的元素
voidlua_getfield(lua_State*L,intindex,constchar*k)
操作:arr=Stack[index]//arr肯定是表
Stack.push(arr[k])
取表中键为k的元素,这里的表是由index指向的栈上的一个表
无返回值
栈高度+1,栈顶元素是(Stack[index])[k]
注意,该操作将触发__index元方法
3.给表中的元素赋值
voidlua_setfield(lua_State*L,intindex,constchar*k)
操作:arr=Stack[index]
arr[k]=Stack.top()
Stack.pop()
给表中键为k的元素赋值value(value就是栈顶元素),这里的表是由index指向的栈上的一个表
无返回值
栈高度-1,被弹出的是value
注意,该操作将触发__newindex元方法
4.取表元素和表元素赋值
voidlua_gettable(lua_State*L,intindex)
操作:ele=Stack[index]
key=Stack.top()
Stack.pop()
value=ele[key]
Stack.push(value)
根据index指定取到相应的表;取栈顶元素为key,并弹出栈;获取表中key的值压入栈顶.
无返回值
栈高度不变,但是发生了一次弹出和压入的操作,弹出的是key,压入的是value
注意,该操作将触发__index元方法
voidlua_settable(lua_State*L,intindex)
操作:ele=Stack[index]
value=Stack.top()
Stack.pop()
key=Stack.top()
Stack.pop()
ele[key]=value
根据index指定取到相应的表;取栈顶元素做value,弹出之;再取当前栈顶元素做key,亦弹出之;然后将表的键为key的元素赋值为value
无返回值
栈高度-2,第一次弹出value,第二次弹出key
注意,该操作将触发__newindex元方法
5.对table的一些操作[不引发原方法]
voidlua_rawget(lua_State*L,intindex)
和lua_gettable操作一样
但是不触发相应的元方法
voidlua_rawgeti(lua_State*L,intindex,intn)
操作:ele=Stack[index]
value=ele
Stack.push(value)
无返回值
栈+1,栈顶新增元素就是value
不触发相应的元方法
voidlua_rawset(lua_State*L,intindex)
和lua_settable操作一样
但是不触发相应的原方法
voidlua_rawseti(lua_State*L,intindex,intn)
操作:ele=Stack[index]
value=Stack.top()
Stack.pop()
ele
=value
无返回值
栈-1,栈顶将value弹出
不触发相应的元方法
6.复制栈上元素并压入栈
voidlua_pushvalue(lua_State*L,intindex)
操作:value=Stack[index]
Stack.push(value)
无返回值
栈+1
7.创建一个元表
intluaL_newmetatable(lua_State*L,constchar*tname)
操作:1.在注册表中查找tname,如果已经注册,就返回0,否者继续,并平栈
lua_getfield(L,LUA_REGISTRYINDEX,tname)
if(!lua_isnil(L,-1))
return0;
lua_pop(L,1);
2.创建一个表,并注册,返回1
lua_newtable(L)
lua_pushvalue(L,-1)
lua_setfield(L,LUA_REGISTRYINDEX,tname)
return1
有返回值
栈+1,栈顶元素是在注册表中注册过的新表
8.创建C值
void*lua_newuserdata(lua_State*L,size_tsize)
该函数分配一块由size指定大小的内存块,并放在栈顶
返回值是新分配的块的地址
栈+1,栈顶是userdata
userdata用来在lua中表示c中的值.一个完整的userdata有自己的元表,在垃圾回收时,可以调用它的元表的__gc方法
9.注册c函数到lua中,其实没有这回事,lua中只有c闭包
voidlua_pushcclosure(lua_State*L,lua_CFunctionfn,intn)
向栈上压一个C闭包
当一个c函数被创建时,可以绑定几个值在它上面,从而形成一个闭包.在任何时刻调用这个c函数时,都可以访问这几个绑定值.
绑定的方法:先一次压入要绑定的n个值到栈上,然后调用lua_pushcclosure(L,fn,n)这样就形成的一个c闭包
无返回值
栈–(n-1),一共弹出n个元素(及那些绑定的值),压入一个cclosure
#definelua_pushcfunction(L,f)lua_pushcclosure(L,f,0)
#definelua_register(L,n,f)(lua_pushcfunction(L,f),lua_setglobal(L,n))
没有返回值
栈不变化
这个是比较常用的,以n为lua中的key压入一个0个绑定值的cclosure.
10.调用一个lua函数
voidlua_call(lua_State*L,intnargs,intnresults)
luacapi的特点就是"不是一个人在战斗"[我想表达的意思是,lua中的一句话,在capi实现起来就是n句,可能有人疑惑那为什么不直接用lua多好,capi这么麻烦,答案是有的事只能用capi才能实现],所以,调用它之前,需要布局一下栈,第一,要把要call的函数压入栈;第二,call要用的参数正序压入栈中;然后才能调用lua_call,调用完了,自己去取返回值,它都给你压栈上了.
操作:
argn=Stack.pop()
...//一共压入nargs个参数
arg2=Stack.pop()
arg3=Stack.pop()
func=Stack.pop()//函数本身也弹出
res1,res2,...,resj=func(arg1,arg2,...,argn)
Stack.push(res1)
Stack.push(res2)
…//压入nresults个返回值
Stack.push(resj)
无返回值
调用结束后,栈高度增加nresults–(1+nargs),如果将nresults参数设置为LUA_MULTRET,那么lua返回几个值,栈上就压入几个值,否者强制压入nresults个值,不足的是空值,多余的抛弃掉
注意,这个函数是有危险的,如果在其中发生了错误,会直接退出程序
这个函数的用途:尚未发现,除非你能接受出错立马退出,反正我是做游戏的,我受不起,呵呵,顺便一说,lauxlib.h中的luaL_check*一族函数也是这样的,不符合预期的话,直接退出,这些函数都要小心,有类似于断言的效果.
11.保护下调用一个lua函数
intlua_pcall(lua_State*L,intnargs,intnresults,interrfunc)
参数,行为和lua_call都一样,如果在调用中没有发生任何错误,lua_pcall==lua_call;但是如果有错误发生时,lua_pcall会捕获它
errfunc指出了Stack上的一个元素,这个元素应该是一个函数,当发生错误的时候
ef=Stack[errfunc]
value=ef(errmsg)
Stack.push(value)
也就是说,在错误的时候,errfunc指定的错误处理函数会被调用,该处理函数的返回值被压到栈上.
默认情况下,可以给errfunc传值0,实际的效果是指定了这样一个函数做出错处理functiondefaulterr(errmsg)returnerrmsgend.
本函数有返回值LUA_ERRRUN运行时错误LUA_ERRMEM内存分配错误[注意,这种错会导致lua调用不了错误处理函数]LUA_ERRERR运行错误处理函数时出错了,写程序的时候必须检查返回值:)
强烈推荐该函数,不过事实上大家也都用的这个函数:)
12.保护下调用一个c函数
intlua_cpcall(lua_State*L,lua_CFunctionfunc,void*ud)
以保护模式调用c函数,func中可以且只能从堆栈上拿到一个参数,就是ud,当有错误时,和lua_pcall返回相同的错误代码,并在堆栈顶部留下errmsg字符串,调用成功的话它返回零,并且不会修改堆栈,所有从func中返回的值都被扔掉.
这里注意的问题是:
1."当有错误时",这个错误的意思是lua的错误,而不是c/c++的错误.在func中使用lua_call和lua_check*族函数,并不会导致程序退出了,而是表现的像lua_pcall那样.
2.调用成功的时候func中的返回值都被扔掉了.
相关文章推荐
- Lua 中的常用API
- skynet lua服务常用API
- Lua5.1的常用API
- lua中string常用api
- 09---java中常用api
- Java 常用API的运用,效率及技巧
- Javascript操作DOM常用API总结
- html canvas 常用api基础
- Java学习笔记之常用API学习笔记3
- 15-10-常用对象API(String类-练习2-子串的次数)
- 15-StringBuffer-13-常用对象API(StringBuilder类-练习)
- 17-集合框架-15-常用对象API(集合框架-ArrayList集合存储自定对象)
- 转载和积累系列 - Lua常用
- 常用的免费api
- Objective-C中基本数据烦类型与对象数据类型相互转换的方法(OC中NSString的常用API的基础应用3)
- drupal7 常用API
- ECMAScript6常用api介绍与使用
- VSCode插件开发全攻略(九)常用API总结
- ehcache常用API整理
- OpenGL常用API