lua中棧的詳細流程

2021-06-29 09:10:34 字數 3369 閱讀 7798

**:

這幾天研究了一下lua,主要關注的是lua和vc之間的整合,把**都寫好放在vc宿主程式裡,然後在lua裡呼叫宿主程式的這些**(或者叫介面、元件,隨便你怎麼叫),希望能用指令碼來控制主程式的行為。這實際上也是一種把業務分離,用指令碼控制的架構,可能有些人把這種指令碼叫做業務引擎,工作流等。

為什麼選擇lua?

因為它是乙個能和c/c++結合得很緊的指令碼語言,而我們的程式是用vc++ 寫的;另外一點是因為它的名氣,連wow都用lua來提供api讓玩家修改其遊戲行為,那我是找不到什麼理由拒絕它了。

lua是什麼?在**獲取lua?

lua和vc mfc的整合?

extern "c"

lua_state *lua;

在某個適當的地方(我是在oninitdialog裡)呼叫下面一段**,這段**的作用是開啟一些必要的庫:

lua = lua_open (); 

if(lua)

用完lua的時候,呼叫下面一句來關閉lua庫:

lua_close (lua);

好了,到現在為止,lua已經完全變成我們程式的一部分了,試著編譯一下,看看能不能順利通過。。。

lua和mfc的互動?

lua變成我們程式的一部分之後,我們還要使用它,要記住我們的目標是用指令碼程式控制我們宿主程式的執行流程,那我們就要完成兩步,一是用mfc程式呼叫lua的函式,二是用lua呼叫mfc的函式,下面的內容對於初學者可能會開始有點難理解了,請打醒十二分精神,我會盡量簡單的說。。。

1、 mfc呼叫lua的函式,這裡用到乙個stackdump的函式,是關於主程式和lua的互動棧的問題,下面會對互動棧的問題專門說明。

首先我們用記事本建立乙個test.lua,內容是乙個相加函式:

function add ( x, y )

return x + y;

end

然後再vc裡呼叫它,如下的一段**,看這段**的時候,先把stackdump函式忽略,只需要知道它是乙個輸出lua和vc互動棧內容的函式,對了,你可以新建乙個button的click函式,然後把這段**放進去:

stackdump(lua);   

lual_dofile(lua, "test.lua");     // 解釋分析lua檔案

stackdump(lua);

lua_getglobal(lua, "add");       // 取到乙個全域性標號add,取的同時會把add函式壓棧

stackdump(lua);   

lua_pushnumber(lua, 1);        // 把第乙個引數壓入棧裡

stackdump(lua);

lua_pushnumber(lua, 2);        // 第二個引數壓棧

stackdump(lua);

//lua_call(lua, 2, 1);

if(lua_pcall(lua, 2, 1, 0) != 0)        // 執行add函式

stackdump(lua);

int d = (int)lua_tonumber(lua, -1);        // 函式執行完了,執行結果被壓棧,所以取得最頂端的乙個數就是結果值,-1就是指取棧頂的值

cstring str;

str.format("%d", d);

afxmessagebox(str);

stackdump(lua);

lua_pop(lua, 1);      // 把值從棧裡清除,pop(彈出)乙個值

stackdump(lua);

好好分析一下這段**,我們大概知道呼叫lua函式的乙個過程是:dofile--〉函式名壓棧--〉引數依序壓棧--〉lua_pcall執行(執行結果壓棧)--〉取出執行結果(如果有多個,就從棧裡取出多個。。。),這樣我們就能很輕鬆的呼叫到lua裡的函式,其實就是要知道棧裡發生了什麼。。。

2、 lua呼叫mfc函式,比如我們想在lua裡呼叫乙個msg函式,能彈出乙個視窗來顯示我們想顯示的字串,然後返回值是1個"msgok!"字串。

lua檔案是這樣的,第一句是呼叫msg函式,第二句是測試返回的字串是不是"msgok!":

c = msg ("123");

msg(c);

mfc程式裡是這樣的:

static int msg(lua_state* l)

然後就匯出這個函式,如下:

lua_pushcfunction(lua, msg);

lua_setglobal(lua, "msg");

接著就執行剛才的lua檔案就行了,記得執行之前要先lua_open () 哦:

lual_dofile(lua, "test.lua");

執行的結果就是連續跳出兩個messagebox,第乙個是123,第二個是"msgok!",說明我們返回的字串被lua接收到了,lua的第二行我們沒有接收它的返回值,則這個返回值會自動被拋棄了。

如果需要多返回值,則我們要把下面一句:

lua_pushlstring(l, "msgok!", 6);  // 把返回值壓進棧裡

// 這個返回是指返回值的個數

return 1;

改為:lua_pushlstring(l, "msgok!", 6);  // 把返回值壓進棧裡

lua_pushlstring(l, "haha!", 5);      // 把返回值壓進棧裡

// 這個返回是指返回值的個數

return 2;

這樣我們在lua檔案裡就可以像下面一樣取得兩個返回值了:

c,d = msg("123");

那c和d就分別是"msgok!"和"haha!"兩個字串了。 這種自動機制用起來還是比較方便的。

3、互動棧

上面兩個呼叫其實都是對lua棧的實用,那我們就要好好理解乙個概念,lua和vc的互動棧(棧是什麼?請參考資料結構的書哈。。。)lua和vc就是通過這個棧來實現互動的,這個棧的訪問函式有lua_gettop,lua_settop,lua_tostring,lua_to***等等的函式,我們要清楚當乙個函式呼叫發生的時候,棧裡是發生了什麼。上面我用了乙個stackdump函式,當我們呼叫的時候,能很清楚的看到棧裡發生了什麼。

首先我們要知道從棧頂往下數就是-1、-2,從棧底往上數就是1、2。

如果使用lua_gettop(l, 1),就是取得棧底第乙個元素。lua_gettop(l, -1)就是取得棧頂的第乙個元素。lua_pop() (l, 1)就是把棧頂的乙個元素彈出來,lua_pop()(l, 2)就是把棧頂的兩個元素彈出。

好了,寫了一通,最後是這個stackdump函式的實現:

int stackdump(lua_state* l)

outputdebugstring("/n"); }

return 0; }

MapReduce詳細流程

1.首先maptask的map方法會生成一堆 k,v 型別的資料,資料會標記好它的分割槽,然後會把這些資料傳入到記憶體的環形緩衝區當中 預設100m 2.當環形緩衝區的記憶體占用達到80 時,從記憶體緩衝區不斷溢位到本地磁碟檔案,可能會溢位多個檔案 在溢位前對資料進行快速排序,排序按照key進行字典...

Django詳細流程

我們以學生管理系統為例,講解一下django的基本操作。首先要設計一下表的結構,這裡就不多解釋 班級表結構 表名 grades 字段 班級名稱 gname 成立時間 gdate 女生總數 ggirlnum 男生總數 gboynum 是否刪除 isdelete 學生表結構 表名 students 字段...

教師面試詳細流程

教師資格證面試詳細流程 第一次寫面試流程,沒有寫過,就以本人當時考試說一下吧,希望大家不要介意哈,先祝大家都能通過面試,加油!我們都有自己的面試准考證,當距離考試半小時前我們進入考場,就從這裡開始寫吧 1.進場 拿著自己身份證和准考證進入學校,進入安排的教室等待,在這個教室裡,有很多和你一起考試的小...