Lua和C的交互说明(函数)

上传人:公**** 文档编号:505455684 上传时间:2023-06-04 格式:DOC 页数:6 大小:43.50KB
返回 下载 相关 举报
Lua和C的交互说明(函数)_第1页
第1页 / 共6页
Lua和C的交互说明(函数)_第2页
第2页 / 共6页
Lua和C的交互说明(函数)_第3页
第3页 / 共6页
Lua和C的交互说明(函数)_第4页
第4页 / 共6页
Lua和C的交互说明(函数)_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《Lua和C的交互说明(函数)》由会员分享,可在线阅读,更多相关《Lua和C的交互说明(函数)(6页珍藏版)》请在金锄头文库上搜索。

1、Lua和C的交互说明(函数)学习各种外挂制作技术,马上去百度搜索“魔鬼作坊”点击第一个站进入、快速成为做挂达人。Lua与C交互(1)lua.newtablevoidlua_newtable(hia_State*L);创建一个空table,并将之压入堆栈。它等价J*lua_createtable(L,0,0)。luagettopmthia_gettop(hia_State*L);返回栈顶元索的索引。因为索引是从1开始编号的,所以这个结果等于堆栈丄的元素个数(因此返回0表示堆栈为空)。luaL.newmetatableintluaL_newmetatable(lua_State*L,constch

2、ar*tname);如果注册表中已经有Key为tname的数据则返回0.否则创建一个新表作为userdata的metatable,并在注册表中注册它然后返回1.不过两种情况都会把注册表中tname相关的值压入堆栈。luaL_checkudatavoid*kiaLcheckudata(lua_State*L,intnaig,constchar*tname);Checkswhetherthefunctionargumentnagisauserdataofthetypetname(seeluaL_newmetatable).Iua_pushstringvoidhia_pushstrmg(lua_St

3、ate*L,constchar*s);把指针s指向的以零结尾的字符串压栈。Lua对这个字符串做二次内存拷贝(或是复用一个拷贝),因此s处的内存在函数返回后,可以释放掉或是重用J:其它用途。字符串中不能包含有零字符;第一个碰到的零字符会认为是字符串的结束。lua_pushlstringvoidhia_pushlstnng(hia_Stateconstcharts,size_tlen);把扌&针s扌旨向的长度为len的字符串压栈。Lua对这爪字符串做一次内存拷贝洽是复用一个拷贝),因此s处的内存在函数返回后,可以释放掉或是重用r其它用途。字符串内可以保存有零字符。lua_pushvaluevoid

4、hia_pushvalue(hiaState*L,intindex);把堆栈上给疋仃效处索引处的元素作一个拷WJk栈。luasettablevoidhasettable(hiaState*L,intindex);作一个等价J;tk二v的操作,这里t是有效索1index处禹值,v指栈顶的值,而k是栈顶之卜的那个值。这个函数会把键和值都从堆栈中弹出。和在Lua中一样,这个函数可能触发newindex事件的元方法(参见2.8)。lua_pushcfunctionvoidhia_pushcfimction(lua_State*L,lua_CFunctionf);将个C函数丿k入川栈。这个函数接收一个C

5、函数指针,并蒋一个类型为function的Lua值压入堆栈。当这个栈定的值被调用时,将触发对应的C函数。注册到Lua中的任何函数都必须遵循正确的协议來接收参数和返回值(参见lua_CFunction)olua_pushcfunction是作为一个宏定义出现的:#definelua_pushcfiinction(L,f)hia_pushcclosuie(L,f,0)Iuasetmetatableinthiasetmetatable(lua_State*L,intindex);把一个table弹出堆栈,并将其设为给定索引处的值的metatable。Iua_pushcclosurevoidhia_p

6、iishcclosme(kia_State*L,hia_CFunctionfii,mtn);把个新的Cclosure压入堆栈。当创建了一个C函数后,你可以给它关联一些值,这样就是在创建一个Cclosure(参见3.4);接卜來无论函数何时被调用,这些值都可以被这个函数访问到。为了将一些值关联到一个C函数上,首先这些值需要先被压入堆栈(如果有多个值,第一个先压)。接下來调ffllua_pushcclosure来创建出closure并把这个C函数压到堆栈I:.参数n告Z函数仃笫少个值需要关联到函数上lua_pushcclosure也会把这吐值从栈上弹出。lua.newuserdatavoid*hi

7、a_newuserdata(hia_State*L,size_tsize);这个函数分配分配块扌旨疋人小的内存块,把内存坯也址作为一个完羲的userdat:压入堆栈,并返回这个地址。userdata代表Lua中的C值。完整的userdata代表一块内存。它是一个对彖(就像table那样的対彖):你必须创建它,它有着自己的元表,而且它在被回收时,可以被监测到。一个完整的userdata只和它自己相等(在等于的原生作用卜当Lua通过gc尤方法回收一个完整的userdata时,Lua调用这个尤方法并把userdata标记为已终止。等到这个userdata再次被收集的时候,Lua会释放掉相关的内存。l

8、ua.touserdatavoid*lua_touserdata(lua_State*L,intindex);如果给定索引处的值是一个完整的userdata,函数返回内存块的地址。如果值是一个lightuserdata,那么就返回它表示的指针。否则,返回NULL“Lua调用C+类要点:1.为此类建立一个全局表,表名为类名tbClass:lua_newtable(L);intmethods=lua_gettop:L);luaj)ushstring(L,T:className);luaj)ushvalue(L,methods);lua.settableiL,LUAGLOBALSINDEX);2.

9、注册一个key为T:className的metatable,并制定其中的一些成员,用J:之后生成的userdata/这个表用Juserdata(T的对象)的metatableluaLnewmetatabieCL,T:className);intmetatable=lua_gettopL);Itmetatabier_index=tbClasslua_pushliteralL,M_index*);lua_pushvalue(L,methods);lua_settable:L,metatable);/metatabte_tostring=tostring_Tlua_pushliteralL,H_to

10、string);lua_pushcfunction(L,tostring_T);lua_settable(L,metatable);IImetatablePacMl=acTlua_pushliteralL,_c”);lua_pushcfunction(L,gc_7);lua_settable:L,metatable);3. 为此表指定成员,每个成员的key为类的成员函数名,Value为一个带有闭包的统一函数。比如tbClassFunName=thunk,之后可以根据闭包得到具体是调用到哪个函数。闭包中有函数名和相应函数的组合结构(以lightuserdata的形式赋给闭包)。这些类成员函数参数

11、都必须包括lua_State,因为它需要的参数都会在lua堆栈中。/为tbClass填充成员函数for(RegTvpe*1=T二methods;l-name;I+)/*editedbySnaily:shouldntitbeconstRegType*1.?*/lua_pushstring(L,Aname);U把(函数名屈数地址)pair以lightuserdata的形式作为Cclosure的upvalue入栈luaj)ushlightuserdata(Lf(voicT)l);If把一个新的Cclosure压入堆栈。为upvalue的个数并指定回调函数统一为thunklua_pushcdosure

12、(L,thunK1);lua_settable(L,methods);4. 创建C对彖给脚本使用b二Account.new(Account,30);new是tbClass卜的一个函数(另外指定的,不会掉到thunk,这一句会调用到C的一个函数,里面会生成一个C对彖,然后创建一个userdata用J咲联到这个新生成的C对彖。最后为这个userdata绑定上我们上面注册为T二classname的metatable因为定制了metatable的_index成员,所以当userdata找不到的成员会去调用index,因为之_前我们把index绑定到tbClass,所以也会调用到tbClass的相应成员

13、。创建个新的T对線.并创建-个賊于userdataType的userdata.实中保护了指向T对象的拆针staticintnew_T(lua_State*L)lua_remove(Lt1);/usedassname:new(),insteadofclassname.ne.v()T*obj=newT(L);/callconstructorforTobjectsuserdataTypeud=static_cast(lua_newuserdata(L,sizeof(userdataType);ud-pT=obj;/storepointertoobjectinuserdataluaL_getmetat

14、able(L,T:className);/lookupmetatableinLuaregistrylua_setmetatable(L,-2);return1;/userdatacontainingpointertoTobject5. 当脚本中指定函数被调用的时候,比如bdeposit(50-30)的时候,b是userdata,它的metatable的_index和tbClass绑定(见4),所以会调用到tbClass的相应成员,就是之_前关联的thunk:这个时候L的堆栈里而有这个函数的两个参数,一个是b本身,一个是50.30.b是userdata,可以根据它取出刈豫的指针。见第4步。另外函

15、数被调用的时候,它相关的upvalue也可以取得到,见步骤3。有了刈豫指针和相应的函数,调用也不为难了,记住参数50-30是保存在堆栈中传给类的成员函数来取得。II所彳j成员函数都会调用到这里,然品根据upvalue來执行具体的成员凶数staticintthunk(lua_State*L)/stackhasuserdata,followedbymethodargsT*obj=check(L.1);/theobjectpointerfromthetableatindex0.Iua_remove(Lt1);IIremoveselfsomemberfunctionargsstartatindex1/getmemberfunctionfromupvalueRegType*l=static_cast(luaJouserdata(L,lua_upvalueindex(1);return(obj-*(l-mfunc)(L);/callmemberfunction根据拆定位iftnarg获得对線拆针,这个userdata/在new_T的时候创建的staticT*check(lua_State*L,intna

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号