国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

淺析C/C++和Lua的通信方式

2024-07-21 23:04:05
字體:
供稿:網(wǎng)友

為了實(shí)現(xiàn)Lua和其他語言之間的通信,Lua虛擬機(jī)為C/C++提供了兩個(gè)特性:

一,Lua_State狀態(tài)機(jī)

       lua_State主要是管理一個(gè)lua虛擬機(jī)的執(zhí)行環(huán)境, 一個(gè)lua虛擬機(jī)可以有多個(gè)執(zhí)行環(huán)境。Lua虛擬機(jī)通過維護(hù)這樣一個(gè)虛擬棧來實(shí)現(xiàn)兩種之間的通信,lua_State定義如下:

struct lua_State { CommonHeader; lu_byte status; StkId top; /* first free slot in the stack */ global_State *l_G; CallInfo *ci; /* call info for current function */ const Instruction *oldpc; /* last pc traced */ StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ int stacksize; unsigned short nny; /* number of non-yieldable calls in stack */ unsigned short nCcalls; /* number of nested C calls */ lu_byte hookmask; lu_byte allowhook; int basehookcount; int hookcount; lua_Hook hook; GCObject *openupval; /* list of open upvalues in this stack */ GCObject *gclist; struct lua_longjmp *errorJmp; /* current error recover point */ ptrdiff_t errfunc; /* current error handling function (stack index) */ CallInfo base_ci; /* CallInfo for first level (C calling Lua) */};

        1,虛擬棧的管理, 包括管理整個(gè)棧和當(dāng)前函數(shù)使用的棧的情況

        2,CallInfo的管理, 包括管理整個(gè)CallInfo數(shù)組和當(dāng)前函數(shù)的CallInfo

        3,hook相關(guān)的, 包括hookmask, hookcount, hook函數(shù)等

        4,global_State是全局唯一的,存放多個(gè)lua_State之間的一些共享數(shù)據(jù)

        5,gc的一些管理和當(dāng)前棧中upvalue的管理

        6,錯誤處理的支持等等

        C/C++和Lua擁有不同的數(shù)據(jù)類型,要實(shí)現(xiàn)兩者之間的數(shù)據(jù)通信怎么辦?Lua虛擬機(jī)提供Lua_State這樣一種數(shù)據(jù)結(jié)構(gòu)。任何一種數(shù)據(jù)從C/C++傳入Lua虛擬機(jī)中,Lua都會將這類數(shù)據(jù)轉(zhuǎn)換為一種通用的結(jié)構(gòu)lua_TValue,并且將數(shù)據(jù)復(fù)制一份,將其壓入虛擬棧中。lua_TValue定義如下:

struct lua_TValue { TValuefields;}; #define TValuefields /  union { struct { Value v__; int tt__; } i; double d__; } u union Value { GCObject *gc;  /* collectable objects */ void *p;     /* light userdata */ int b;      /* booleans */ lua_CFunction f; /* light C functions */ numfield     /* numbers */};

       Lua有自己的GC,C/C++由自己申請和釋放內(nèi)存,所以兩者之間的內(nèi)存管理是獨(dú)立的。從C/C++中傳遞數(shù)據(jù)到Lua虛擬機(jī)會發(fā)生數(shù)據(jù)拷貝,從Lua虛擬機(jī)中傳遞出來是直接從虛擬棧中取值或者地址,所以數(shù)據(jù)從虛擬棧中pop之后,是否依然是有效引用需要額外注意。

 二,C API

Lua腳本實(shí)現(xiàn)交互提供了一系列的C API,常用API有:

        luaL_newstate函數(shù)用于初始化一個(gè)lua_State實(shí)例

        luaL_openlibs函數(shù)用于打開Lua中的所有標(biāo)準(zhǔn)庫,如io庫、string庫等。

        luaL_loadbuffer編譯了buff中的Lua代碼,如果沒有錯誤,則返回0,同時(shí)將編譯后的程序塊壓入虛擬棧中。

        lua_pcall函數(shù)會將程序塊從棧中彈出,并在保護(hù)模式下運(yùn)行該程序塊。執(zhí)行成功返回0,否則將錯誤信息壓入棧中。

        lua_tostring函數(shù)中的-1,表示棧頂?shù)乃饕担瑮5椎乃饕禐?,以此類推。該函數(shù)將返回棧頂?shù)腻e誤信息,但是不會將其從棧中彈出。

        lua_pop是一個(gè)宏,用于從虛擬棧中彈出指定數(shù)量的元素,這里的1表示僅彈出棧頂?shù)脑亍?/p>

        lua_close用于釋放狀態(tài)指針?biāo)玫馁Y源。

入棧操作:

        Lua針對每種C類型,都有一個(gè)C API函數(shù)與之對應(yīng),如:

        void lua_pushnil(lua_State* L);  --nil值

        void lua_pushboolean(lua_State* L, int b); --布爾值

        void lua_pushnumber(lua_State* L, lua_Number n); --浮點(diǎn)數(shù)

        void lua_pushinteger(lua_State* L, lua_Integer n);  --整型

        void lua_pushlstring(lua_State* L, const char* s, size_t len); --指定長度的內(nèi)存數(shù)據(jù)

        void lua_pushstring(lua_State* L, const char* s);  --以零結(jié)尾的字符串,其長度可由strlen得出。

出棧操作:

        API使用“索引”來引用棧中的元素,第一個(gè)壓入棧的為1,第二個(gè)為2,依此類推。我們也可以使用負(fù)數(shù)作為索引值,其中-1表示為棧頂元素,-2為棧頂下面的元素,同樣依此類推。

        Lua提供了一組特定的函數(shù)用于檢查返回元素的類型,如:

        int lua_isboolean (lua_State *L, int index);

        int lua_iscfunction (lua_State *L, int index);

        int lua_isfunction (lua_State *L, int index);

        int lua_isnil (lua_State *L, int index);

        int lua_islightuserdata (lua_State *L, int index);

        int lua_isnumber (lua_State *L, int index);

        int lua_isstring (lua_State *L, int index);

        int lua_istable (lua_State *L, int index);

        int lua_isuserdata (lua_State *L, int index);

        以上函數(shù),成功返回1,否則返回0。需要特別指出的是,對于lua_isnumber而言,不會檢查值是否為數(shù)字類型,而是檢查值是否能轉(zhuǎn)換為數(shù)字類型。

如有任何疑問和建議,歡迎指出討論,謝謝~

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 吉水县| 巴彦淖尔市| 临夏市| 芦溪县| 罗源县| 丰城市| 曲阳县| 蒲城县| 修文县| 榆树市| 隆德县| 寻乌县| 竹山县| 班戈县| 轮台县| 乌鲁木齐县| 博白县| 庆阳市| 和田市| 黎平县| 富民县| 宁河县| 青海省| 溧水县| 武胜县| 南汇区| 壤塘县| 寻甸| 贵港市| 广昌县| 满城县| 绵阳市| 盖州市| 岳池县| 于田县| 东兰县| 漳浦县| 阜平县| 东莞市| 东乡族自治县| 赤城县|