lua中棧

    首先咱們來說一下棧:
api

    lua與c語言通信的主要方法是經過一個無所不在的虛擬棧。幾乎全部的api調用都會操做這個棧上的值:全部的數據交換,不管是lua到c語言或c語言到lua都是經過這個棧來完成。棧能夠解決lua與c語言之間存在的兩大差別,第一個差別時lua使用垃圾回收收集,而c語言要求顯示地釋放內存;第二種是lua使用動態類型,而c語言使用靜態類型。
函數

    咱們來看一下c與lua之間是怎麼通信的:(假如c語言想知道lua中的money字符串的值
lua

    1.c想獲取lua中的money字符串的值,須要c把money房放到棧頂,以便lua能看到。
spa

    2.lua從棧頂中獲取money,此時棧頂再次變爲空
指針

    3.lua經過money這個字段在其全局表中進行查找
code

    4.全局表返回money對應的值,假設爲10000
索引

    5.lua把取得的10000放到棧頂
內存

    6.c能夠從棧頂取得10000
rem

    

    咱們來看一下棧的操做:
字符串

    1.壓入棧:

    對於每種能夠呈如今lua中的c類型,api都有一個對應的壓入函數,以下:

void lua_pushnil(lua_State *L);
void lua_pushboolean(lua_State *L, int bool);
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 len);
void lua_pushstring(lua_State *L, const char *s);

    2.查詢元素:

    api使用索引來訪問棧中的元素。第一個壓入棧中的元素索引爲1,第二個壓入的元素索引爲2,以此類推,直到棧頂。我麼也能夠用棧頂做爲參考物,使用負數來訪問棧中的元素。此時-1表示棧頂元素,-2表示棧頂下面的元素,以此類推。

    爲了檢查一個元素是否爲特定的類型,api提供了一系列的函數lua_is*,其中*能夠是任意lua類型。這些函數有lua_number、lua_isstring和lua_istable等,原型以下:

int lua_is*(lua_State *L, int index);

    3.取值:

    咱們通常使用lua_to*函數從棧中獲取一個值,以下:

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);
size_t          lua_objlen (lua_State *L, int idx);
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);

    若是指定的元素不具備正確的類型,調用這些函數也不會有問題。在這種狀況下,lua_toboolean、lua_tonumber、lua_tointeger和lua_objlen會返回0,而其它函數會返回NULL。lua_tolstring函數會返回一個指向內部字符串副本的指針,並將字符串的長度存入最後一個參數len中。這個內部副本不能修改,返回類型中的const也說明了這點。Lua保證只要這個對應的字符串還在棧中,那麼這個指針就是有效的。當Lua調用的一個C函數返回時,Lua就會清空它的棧。

    棧的其它操做:

--返回棧中元素的個數,也能夠說是棧頂元素的索引
int   lua_gettop (lua_State *L);    
--將棧頂設置爲一個指定的位置,即修改棧中元素的數量,若是以前的棧頂比新設置的更高,那麼高出來的這些元素會被丟棄--;反之,會向棧中壓入nil來補足大小.lua_settop(L, 0);表示清空棧
void  lua_settop (lua_State *L, int idx);
--將指定索引上值得副本壓入棧
void  lua_pushvalue (lua_State *L, int idx);
--刪除指定索引上的元素,並將該位置之上的全部元素下移以填補空缺
void  lua_remove (lua_State *L, int idx);
--上移指定位置之上的全部元素以開闢一個槽空間,而後將棧頂元素移到該位置
void  lua_insert (lua_State *L, int idx);
--彈出棧頂的值,並將該值設置到指定索引上,但它不會移動任何東西,只是替換了指定索引的值
void  lua_replace (lua_State *L, int idx);
相關文章
相關標籤/搜索