解析Lua 5.1中關(guān)于API函數(shù)學(xué)習(xí)教程
Lua 5.1中關(guān)于API函數(shù)學(xué)習(xí)教程是本文要介紹的內(nèi)容,主要是來學(xué)習(xí)API函數(shù)在lua中的應(yīng)用,具體內(nèi)容來看本文詳解。
- lua_State* luaL_newstate()
Lua腳本的編譯執(zhí)行是相互獨(dú)立的,在不同的線程上執(zhí)行。通過luaL_newstate()函數(shù)可以申請(qǐng)一個(gè)虛擬機(jī),返回指針類型 lua_State。今后其他所有Lua Api函數(shù)的調(diào)用都需要此指針作為***參數(shù),用來指定某個(gè)虛擬機(jī)。
- lua_State* L = luaL_newstate();
- void lua_close(lua_State *L)
銷毀指定 Lua 狀態(tài)機(jī)中的所有對(duì)象(如果有垃圾收集相關(guān)的元方法的話,會(huì)調(diào)用它們),并且釋放狀態(tài)機(jī)中使用的所有動(dòng)態(tài)內(nèi)存。在一些平臺(tái)上,你可以不必調(diào)用這個(gè)函數(shù),因?yàn)楫?dāng)宿主程序結(jié)束的時(shí)候,所有的資源就自然被釋放掉了。另一方面,長期運(yùn)行的程序,比如一個(gè)后臺(tái)程序或是一個(gè) web 服務(wù)器,當(dāng)不再需要它們的時(shí)候就應(yīng)該釋放掉相關(guān)狀態(tài)機(jī)。這樣可以避免狀態(tài)機(jī)擴(kuò)張的過大。
- lua_close(L);
- lua_State* lua_newthread(lua_State *L)
- int lua_gettop(lua_State *L)
取得棧的高度
- for (int i = 0; i < 10; ++i)
- lua_pushnumber(L, i);
- printf("%d", lua_gettop(L));
- --> 10
- void lua_settop(lua_State *L, int idx)
設(shè)置棧的高度,如果之前的棧頂比新設(shè)置的更高,那么高出來的元素會(huì)被丟棄,反之壓入nil來補(bǔ)足大小。
另外,Lua提供了一個(gè)宏,用來從棧中彈出n個(gè)元素:#define lua_pop(L, n) lua_settop(L, -(n)-1)將指定索引上值的副本壓入棧
- for (int i = 1; i <= 3; ++i)
- lua_pushnumber(i);
- 棧中元素:(從下往上) 1 2 3
- lua_pushvalue(L, 2)
- 棧中元素:(從下往上) 1 2 3 2
- void lua_remove(lua_State *L, int idx)
刪除指定索引上的元素,并將該位置之上的所有元素下移以補(bǔ)空缺
- for (int i = 1; i <= 3; ++i)
- lua_pushnumber(i);
- 棧中元素:(從下往上) 1 2 3
- lua_remove(L, 2)
- 棧中元素:(從下往上) 1 3
- void lua_insert(lua_State *L, int idx)
移指定位置上的所有元素以開辟一個(gè)空間槽的空間,然后將棧頂元素移到該位置
- for (int i = 1; i <= 5; ++i)
- lua_pushnumber(i);
- 棧中元素:(從下往上) 1 2 3 4 5
- lua_insert(L, 3)
- 棧中元素:(從下往上) 1 2 5 4 3
- void lua_replace(lua_State *L, int idx)
彈出棧頂?shù)闹?,并將該值設(shè)置到指定索引上,但它不會(huì)移動(dòng)任何東西
- for (int i = 1; i <= 5; ++i)
- lua_pushnumber(i);
- 棧中元素:(從下往上) 1 2 3 4 5
- lua_replace(L, 3)
- 棧中元素:(從下往上) 1 2 5 4
- int lua_checkstack(lua_State *L, int sz)
擴(kuò)大棧的可用尺寸,棧的默認(rèn)尺寸是20,此函數(shù)會(huì)確保堆棧上至少有 sz 個(gè)空位。如果不能把堆棧擴(kuò)展到相應(yīng)的尺寸,函數(shù)返回 false 。這個(gè)函數(shù)永遠(yuǎn)不會(huì)縮小堆棧;如果堆棧已經(jīng)比需要的大了,那么就放在那里不會(huì)產(chǎn)生變化。
lua_checkstack(L, 100)
- void lua_xmove(lua_State* from, lua_State* to, int n)
- //access functions (stack -> C)
- int lua_isnumber(lua_State *L, int idx)
- int lua_isstring(lua_State *L, int idx)
- int lua_iscfunction(lua_State *L, int idx)
- int lua_isuserdata(lua_State *L, int idx)
- int lua_isnil(lua_State *L, int idx);
- int lua_isboolean(lua_State *L, int idx);
- int lua_istable(lua_State *L, int idx);
- int lua_isfunction(lua_State *L, int idx);
- int lua_islightuserdata (lua_State *L, int idx);
上面四個(gè)函數(shù)都有一個(gè)同樣的原型int lua_is*(lua_State *L, int index),用來查詢某值是否能轉(zhuǎn)換成某個(gè)類型的值。對(duì)于任意數(shù)字,lua_isstring都返回真。
- lua_pushnumber(L, 994);
- lua_pushstring(L, "hello,lua");
- lua_isnumber(L, 1)-->true
- lua_isnumber(L, 2)-->false
- lua_isstring(L,1)-->true
- int lua_type(lua_State *L, int idx)
得到一個(gè)元素的類型,返回整型,返回值是如下列表之一:
- #define LUA_TNONE (-1)
- #define LUA_TNIL 0
- #define LUA_TBOOLEAN 1
- #define LUA_TLIGHTUSERDATA 2
- #define LUA_TNUMBER 3
- #define LUA_TSTRING 4
- #define LUA_TTABLE 5
- #define LUA_TFUNCTION 6
- #define LUA_TUSERDATA 7
- #define LUA_TTHREAD 8
- lua_pushnumber(L, 55);
- lua_type(L, 1)-->LUA_TNUMBER
- const char* lua_typename(lua_State *L, int tp)
將一個(gè)類型編碼轉(zhuǎn)換成類型名
- lua_typename(L, 1)-->boolean
- lua_typename(L, 3)-->number
- int lua_equal(lua_State *L, int idx1, int idx2)
如果依照 Lua 中 == 操作符語義,索引 index1 和 index2 中的值相同的話,返回 1 。否則返回 0 。如果任何一個(gè)索引無效也會(huì)返回 0。
- lua_pushstring(L, "this");
- lua_pushboolean(L, 1);
- lua_pushboolean(L, 1);
- lua_equal(L, -2, -3)
- -->0
- lua_equal(L, -1, -2)
- -->1
- lua_equal(L, -1, -10)
- -->0
- int lua_rawequal(lua_State *L, int idx1, int idx2)
- int lua_lessthan(lua_State *L, int idx1, int idx2)
- lua_Number lua_tonumber(lua_State *L, int idx)
- lua_Integer lua_tointeger(lua_State *L, int idx)
- int lua_toboolean(lua_State *L, int idx)
- const char* lua_tolstring(lua_State *L, int idx, size_t *len)
以上四個(gè)函數(shù)都有一個(gè)原型lua_to*(lua_State *L, int idx),用于從棧中取一個(gè)值。如果指定的元素不具有正確的類型,調(diào)用這些函數(shù)也不會(huì)有問題,
在這種情況下,調(diào)用lua_toboolean,lua_tonumber,lua_tointeger會(huì)返回0,其它函數(shù)會(huì)返回NULL。通常不使用lua_is*函數(shù),只需在調(diào)用它們之
后測試返回結(jié)果是否為NULL就可以了。
- lua_pushnumber(L, 100)
- lua_tonumber(L, 1)-->100
- lua_pushinteger(L, 200)
- lua_tointeger(L, -1)-->200
- lua_pushboolean(L, 0)
- lua_toboolean(L, -1)-->false
- lua_pushstring(L, "hello,lua")
- lua_tolstring(L, -1, &len)-->hello,lua
注:len是傳出參數(shù),表示字符串的長度,如果想忽略此參數(shù),傳入NULL
- size_t lua_objlen(lua_State *L, int idx)
返回值的長度,如果類型不正確,返回0
- lua_pushstring(L, "hello,lua")
- lua_objlen(L, 1)-->9
- lua_CFunction lua_tocfunction(lua_State *L, int idx)
- void* lua_touserdata(lua_State *L, int idx)
- lua_State* lua_tothread(lua_State *L, int idx)
- const void* lua_topointer(lua_State *L, int idx)
- //push functions (C -> stack)
- void lua_pushnil(lua_State *L)
- void lua_pushnumber(lua_State *L, lua_Number n)
- void lua_pushinteger(lua_State *L, lua_Integer n)
- void lua_pushlstring(lua_State *L, const char* s, size_t l)
- void lua_pushstring(lua_State *L, const char *s)
- const char* lua_pushvfstring(lua_State *L, const char *fmt, va_list argp)
- const char* lua_pushfstring(lua_State *L, const char *fmt, ...)
- void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
- void lua_pushboolean(lua_State *L, void *b)
- void lua_pushlightuserdata(lua_State *L, void *p)
- int lua_pushthread(lua_State *L)
- void lua_gettable(lua_State *L, int idx)
- void lua_getfield(lua_State *L, int idx, const char *k)
把 t[k] 值壓入堆棧,這里的 t 是指有效索引 index 指向的值。在 Lua 中,這個(gè)函數(shù)可能觸發(fā)對(duì)應(yīng) "index" 事件的元方法
- void lua_rawget(lua_State *L, int idx)
- void lua_rawgeti(lua_State *L, int idx, int n)
- void lua_createtable(lua_State *L, int narr, int nrec)
創(chuàng)建一個(gè)新的空 table 壓入堆棧。這個(gè)新 table 將被預(yù)分配 narr 個(gè)元素的數(shù)組空間以及 nrec 個(gè)元素的非數(shù)組空間。當(dāng)你明確知道表中需要多少個(gè)元素時(shí),預(yù)分配就非常有用。如果你不知道,可以使用函數(shù) lua_newtable。
舉例暫缺
- void* lua_newuserdata(lua_State *L, size_t sz)
- int lua_getmetatable(lua_State *L, int objindex)
- void lua_getfenv(lua_State *L, int idx)
把索引處值的環(huán)境表壓入堆棧
- void lua_settable(lua_State *L, int idx);
- void lua_setfield(lua_State *L, int idx, const char *k)
- void lua_rawset(lua_State *L, int idx)
- void lua_rawseti(lua_State *L, int idx, int n)
- int lua_setmetatable(lua_State *L, int objindex)
- int lua_setfenv(lua_State *L, int idx)
- //'load' and 'call' functions (load and run lua code)
- void lua_call(lua_State *L, int nargs, int nresults);
- int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
- int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
以保護(hù)模式調(diào)用 C 函數(shù) func 。 func 只有能從堆棧上拿到一個(gè)參數(shù),就是包含有 ud 的 light userdata。當(dāng)有錯(cuò)誤時(shí), lua_cpcall 返回和 lua_pcall 相同的錯(cuò)誤代碼,并在棧頂留下錯(cuò)誤對(duì)象;否則它返回零,并不會(huì)修改堆棧。所有從 func 內(nèi)返回的值都會(huì)被扔掉。
舉例暫缺
- int lua_load(lua_State *L, lua_Reader reader, void *dt, const char *chunkname);
- int lua_dump(lua_State *L, lua_Writer writer, void *data);
把函數(shù) dump 成二進(jìn)制 chunk 。函數(shù)接收棧頂?shù)?Lua 函數(shù)做參數(shù),然后生成它的二進(jìn)制 chunk 。若被 dump 出來的東西被再次加載,加載的結(jié)果就相當(dāng)于原來的函數(shù)。當(dāng)它在產(chǎn)生 chunk 的時(shí)候,lua_dump 通過調(diào)用函數(shù) writer (參見 lua_Writer)來寫入數(shù)據(jù),后面的 data 參數(shù)會(huì)被傳入 writer 。
***一次由寫入器 (writer) 返回值將作為這個(gè)函數(shù)的返回值返回; 0 表示沒有錯(cuò)誤。
這個(gè)函數(shù)不會(huì)把 Lua 返回彈出堆棧。
舉例暫缺
- int lua_yield(lua_State *L, int nresults)
- int lua_resume(lua_State *L, int narg)
- int lua_status(lua_State *L)
- int lua_gc(lua_State *L, int what, int data)
控制垃圾收集器。 這個(gè)函數(shù)根據(jù)其參數(shù) what 發(fā)起幾種不同的任務(wù):
- * LUA_GCSTOP: 停止垃圾收集器。
- * LUA_GCRESTART: 重啟垃圾收集器。
- * LUA_GCCOLLECT: 發(fā)起一次完整的垃圾收集循環(huán)。
- * LUA_GCCOUNT: 返回 Lua 使用的內(nèi)存總量(以 K 字節(jié)為單位)。
- * LUA_GCCOUNTB: 返回當(dāng)前內(nèi)存使用量除以 1024 的余數(shù)。
- * LUA_GCSTEP: 發(fā)起一步增量垃圾收集。步數(shù)由 data 控制(越大的值意味著越多步),而其具體含義(具體數(shù)字表示了多少)并未標(biāo)準(zhǔn)化。
- 如果你想控制這個(gè)步數(shù),必須實(shí)驗(yàn)性的測試 data 的值。如果這一步結(jié)束了一個(gè)垃圾收集周期,返回返回 1 。
- * LUA_GCSETPAUSE: 把 data/100 設(shè)置為 garbage-collector pause 的新值。函數(shù)返回以前的值。
- * LUA_GCSETSTEPMUL: 把 arg/100 設(shè)置成 step multiplier 。函數(shù)返回以前的值。
- int lua_error(lua_State *L)
產(chǎn)生一個(gè) Lua 錯(cuò)誤。錯(cuò)誤信息(實(shí)際上可以是任何類型的 Lua 值)必須被置入棧頂。這個(gè)函數(shù)會(huì)做一次長跳轉(zhuǎn),因此它不會(huì)再返回。(參見 luaL_error)。
- lua_pushstring(L, "one error");
- lua_error(L);
- printf("%s", "本行已經(jīng)執(zhí)行不到了");
- int lua_next(lua_State *L, int idx)
- void lua_concat(lua_State *L, int n)
連接棧頂?shù)?n 個(gè)值,然后將這些值出棧,并把結(jié)果放在棧頂。如果 n 為 1 ,結(jié)果就是一個(gè)字符串放在棧上(即,函數(shù)什么都不做);如果 n 為 0 ,結(jié)果是一個(gè)空串。 連接依照 Lua 中創(chuàng)建語義完成,如果嘗試把兩個(gè)不能連接的類型連接,程序會(huì)給出錯(cuò)誤提示。
- lua_pushstring(L, "this");
- lua_pushboolean(L, 1);
- lua_pushnumber(L, 9989);
- lua_pushnumber(L, 1111);
- lua_pushboolean(L, 0);
- lua_pushstring(L, "滿天都是小星星");
- lua_pushnumber(L, 1986);
- lua_pushstring(L, "onebyone");
- -->'this' 'true' '9989' '1111' 'false' '滿天都是小星星' '1986' 'onebyone'
- lua_concat(L, 3);
- -->'this' 'true' '9989' '1111' 'false' '滿天都是小星星1986onebyone'
- lua_Alloc lua_getallocf(lua_State *L, void **ud)
返回給定狀態(tài)機(jī)的內(nèi)存分配器函數(shù)。如果 ud 不是 NULL ,Lua 把調(diào)用 lua_newstate 時(shí)傳入的那個(gè)指針放入 *ud 。
- void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
- //Functions to be called by the debuger in specific events
- int lua_getstack(lua_State *L, int level, lua_Debug *ar)
- int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
- const char* lua_getlocal(lua_State *L, const lua_Debug *ar, int n)
- const char* lua_setlocal(lua_State *L, const lua_Debug *ar, int n)
- const char* lua_getupvalue(lua_State *L, int funcindex, int n)
- const char* lua_setupvalue(lua_State *L, int funcindex, int n)
- int lua_sethook(lua_State *L, lua_Hook func, int mask, int count);
- lua_Hook lua_gethook(lua_State *L)
- int lua_gethookmask(lua_State *L)
- int lua_gethookcount(lua_State *L)
小結(jié):解析Lua 5.1中關(guān)于API函數(shù)學(xué)習(xí)教程的內(nèi)容介紹完了希望通過本文的學(xué)習(xí)能對(duì)你有所幫助!