一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Lua - 淺析C\C++和Lua的通信方式

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

2020-04-10 14:43hebedich Lua

lua作為小巧精悍的腳本語言,易于嵌入c/c++中 , 廣泛應用于游戲AI ,實際上在任何經常變化的邏輯上都可以使用lua實現,配合c/c++實現的底層接口服務,能夠大大降低系統的維護成本。

為了實現Lua和其他語言之間的通信,Lua虛擬機為C\C++提供了兩個特性:

一,Lua_State狀態機

       lua_State主要是管理一個lua虛擬機的執行環境, 一個lua虛擬機可以有多個執行環境。Lua虛擬機通過維護這樣一個虛擬棧來實現兩種之間的通信,lua_State定義如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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,虛擬棧的管理, 包括管理整個棧和當前函數使用的棧的情況

        2,CallInfo的管理, 包括管理整個CallInfo數組和當前函數的CallInfo

        3,hook相關的, 包括hookmask, hookcount, hook函數等

        4,global_State是全局唯一的,存放多個lua_State之間的一些共享數據

        5,gc的一些管理和當前棧中upvalue的管理

        6,錯誤處理的支持等等

        C\C++和Lua擁有不同的數據類型,要實現兩者之間的數據通信怎么辦?Lua虛擬機提供Lua_State這樣一種數據結構。任何一種數據從C\C++傳入Lua虛擬機中,Lua都會將這類數據轉換為一種通用的結構lua_TValue,并且將數據復制一份,將其壓入虛擬棧中。lua_TValue定義如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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++由自己申請和釋放內存,所以兩者之間的內存管理是獨立的。從C\C++中傳遞數據到Lua虛擬機會發生數據拷貝,從Lua虛擬機中傳遞出來是直接從虛擬棧中取值或者地址,所以數據從虛擬棧中pop之后,是否依然是有效引用需要額外注意。

 二,C API

Lua腳本實現交互提供了一系列的C API,常用API有:

        luaL_newstate函數用于初始化一個lua_State實例

        luaL_openlibs函數用于打開Lua中的所有標準庫,如io庫、string庫等。

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

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

        lua_tostring函數中的-1,表示棧頂的索引值,棧底的索引值為1,以此類推。該函數將返回棧頂的錯誤信息,但是不會將其從棧中彈出。

        lua_pop是一個宏,用于從虛擬棧中彈出指定數量的元素,這里的1表示僅彈出棧頂的元素。

        lua_close用于釋放狀態指針所引用的資源。

入棧操作:

        Lua針對每種C類型,都有一個C API函數與之對應,如:

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

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

        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);  --以零結尾的字符串,其長度可由strlen得出。

出棧操作:

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

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

        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);

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

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

延伸 · 閱讀

精彩推薦
  • LuaLua教程(二):基礎知識、類型與值介紹

    Lua教程(二):基礎知識、類型與值介紹

    這篇文章主要介紹了Lua教程(二):基礎知識、類型與值介紹,本文講解了Hello World程序、代碼規范、全局變量、類型與值等內容,需要的朋友可以參考下 ...

    腳本之家5922020-04-28
  • LuaLua中table庫函數方法介紹

    Lua中table庫函數方法介紹

    這篇文章主要介紹了Lua中table庫函數方法介紹,本文講解了concat、insert、maxn、remove、sort、foreachi等方法,需要的朋友可以參考下 ...

    腳本之家2502020-04-17
  • LuaLua和C語言的交互詳解

    Lua和C語言的交互詳解

    這篇文章主要介紹了Lua和C語言的交互詳解,Lua和C語言通過棧完成交互,本文結合代碼實例詳細講解了交互的方法,需要的朋友可以參考下 ...

    果凍想3702020-04-14
  • LuaLua中計算、執行字符串中Lua代碼的方法

    Lua中計算、執行字符串中Lua代碼的方法

    這篇文章主要介紹了Lua中計算、執行字符串中Lua代碼的方法,類似JavaScript中eval函數的功能,在Lua中也可以實現,需要的朋友可以參考下 ...

    腳本之家6322020-04-30
  • LuaLua簡介、編譯安裝教程及變量等語法介紹

    Lua簡介、編譯安裝教程及變量等語法介紹

    這篇文章主要介紹了Lua簡介、編譯安裝教程及變量等語法介紹,本文同時講解了lua注釋語法、Lua命令行方式等內容,需要的朋友可以參考下 ...

    junjie3632020-04-14
  • Lua深入探究Lua中的解析表達式

    深入探究Lua中的解析表達式

    這篇文章主要介紹了深入探究Lua中的解析表達式,對于其語法部分的說明和示例都超詳細,極力推薦此文!需要的朋友可以參考下 ...

    腳本之家3542020-05-05
  • LuaLua中的元方法__newindex詳解

    Lua中的元方法__newindex詳解

    這篇文章主要介紹了Lua中的元方法__newindex詳解,本文講解了查詢與更新、監控賦值、通過table給另一個table賦值等內容,需要的朋友可以參考下 ...

    笨木頭8872020-04-09
  • LuaLua實現__add方法重載示例

    Lua實現__add方法重載示例

    這篇文章主要介紹了Lua實現__add方法重載示例,本文直接給出實現代碼,需要的朋友可以參考下 ...

    腳本之家7452020-04-24
主站蜘蛛池模板: 国产卡一卡二卡3卡乱码免费 | 国产伦久视频免费观看视频 | 久久亚洲精品AV成人无 | 成人国产在线视频 | 成年性午夜免费视频网站不卡 | futa巨大好爽好长 | 奇米影视久久 | 免费高清资源黄网站在线观看 | 午夜国产精品福利在线观看 | 婷婷综合亚洲 | 97爱sese | 国产色婷婷亚洲 | 国产麻豆剧果冻传媒观看免费视频 | 国产精品最新 | 成人精品免费网站 | 无人区在线观看免费完整版免费 | 亚洲欧美日本在线观看 | 荷兰精品女人性hd | 色五婷婷 | 草莓秋葵菠萝蜜绿巨人污 | 99午夜高清在线视频在观看 | 禁忌第一季第3季 | 糖心在线观看 | 日本精品vide·ssex日本 | 欧美2区 | 日本高清视频在线观看 | 成年视频在线播放 | 日韩欧美色图 | 第一次做m被调教经历 | 日本四虎影院 | 唯美 清纯 另类 亚洲制服 | 丝袜足控免费网站xx动漫漫画 | 三级小说网站 | 欧美精品国产一区二区 | 欧美日韩国产精品自在自线 | 国产高清在线观看 | 成人性生交小说免费看 | 国产欧美精品一区二区三区四区 | 免费尤物视频 | 国产精品麻豆久久99 | 91东航翘臀女神在线播放 |