自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C\C++和Lua是如何進(jìn)行通信的?

開(kāi)發(fā) 后端 前端
lua本身就是用標(biāo)準(zhǔn)C編寫(xiě)的,它的優(yōu)點(diǎn)是小巧和靈活,而且又是動(dòng)態(tài)語(yǔ)言,是解釋執(zhí)行的,所以適合用在游戲和一些嵌入式環(huán)境里。下面將實(shí)現(xiàn)Lua和其他語(yǔ)言之間的通信……

為了實(shí)現(xiàn)Lua和其他語(yǔ)言之間的通信,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ī)通過(guò)維護(hù)這樣一個(gè)虛擬棧來(lái)實(shí)現(xiàn)兩種之間的通信,lua_State定義如下:

  1. struct lua_State {  
  2.   CommonHeader;  
  3.   lu_byte status;  
  4.   StkId top;  /* first free slot in the stack */ 
  5.   global_State *l_G;  
  6.   CallInfo *ci;  /* call info for current function */ 
  7.   const Instruction *oldpc;  /* last pc traced */ 
  8.   StkId stack_last;  /* last free slot in the stack */ 
  9.   StkId stack;  /* stack base */ 
  10.   int stacksize;  
  11.   unsigned short nny;  /* number of non-yieldable calls in stack */ 
  12.   unsigned short nCcalls;  /* number of nested C calls */ 
  13.   lu_byte hookmask;  
  14.   lu_byte allowhook;  
  15.   int basehookcount;  
  16.   int hookcount;  
  17.   lua_Hook hook;  
  18.   GCObject *openupval;  /* list of open upvalues in this stack */ 
  19.   GCObject *gclist;  
  20.   struct lua_longjmp *errorJmp;  /* current error recover point */ 
  21.   ptrdiff_t errfunc;  /* current error handling function (stack index) */ 
  22.   CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */ 
  23. }; 

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,錯(cuò)誤處理的支持等等

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

  1. struct lua_TValue {  
  2.   TValuefields;  
  3. };  
  4.    
  5. #define TValuefields  \  
  6.     union { struct { Value v__; int tt__; } i; double d__; } u  
  7.    
  8. union Value {  
  9.   GCObject *gc;    /* collectable objects */ 
  10.   void *p; /* light userdata */ 
  11.   int b;   /* booleans */ 
  12.   lua_CFunction f; /* light C functions */ 
  13.   numfield /* numbers */ 
  14. }; 

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

 二,C API

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

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

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

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

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

lua_tostring函數(shù)中的-1,表示棧頂?shù)乃饕?,棧底的索引值?,以此類(lèi)推。該函數(shù)將返回棧頂?shù)腻e(cuò)誤信息,但是不會(huì)將其從棧中彈出。

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

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

入棧操作:

Lua針對(duì)每種C類(lèi)型,都有一個(gè)C API函數(shù)與之對(duì)應(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); --指定長(zhǎng)度的內(nèi)存數(shù)據(jù)

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

出棧操作:

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

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

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。需要特別指出的是,對(duì)于lua_isnumber而言,不會(huì)檢查值是否為數(shù)字類(lèi)型,而是檢查值是否能轉(zhuǎn)換為數(shù)字類(lèi)型。

有關(guān)API的具體用法或者了解更多的API請(qǐng)?jiān)L問(wèn)其官方網(wǎng)站

原文出自:http://my.oschina.net/xlplbo/blog/314956

責(zé)任編輯:林師授 來(lái)源: xlplbo的博客
相關(guān)推薦

2010-01-20 09:32:30

C++類(lèi)

2010-01-20 13:29:40

C++環(huán)境

2010-01-27 15:29:45

C++異常處理

2010-01-20 10:49:29

Visual C++界

2010-02-02 13:04:03

C++頭文件

2010-01-19 14:39:22

C++ Builder

2010-01-15 19:05:42

學(xué)習(xí)C++

2010-01-12 09:59:08

Visual C++

2010-01-22 16:21:50

C++ Builder

2010-02-05 17:16:05

C++構(gòu)造函數(shù)

2010-01-27 10:45:21

C++單例模式

2010-01-28 10:33:10

C++開(kāi)發(fā)程序

2010-01-15 17:31:18

C++Test

2009-08-27 15:33:58

C# Cookie編程

2010-01-15 18:06:20

C++引用

2019-08-28 14:21:39

C++C接口代碼

2020-07-31 18:33:56

C++編程語(yǔ)言

2010-01-22 18:06:24

C++代碼

2010-01-25 14:43:00

C++構(gòu)造函數(shù)

2010-01-22 13:20:27

C++代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)