Lua初學者(四)--Lua呼叫原理展示(lua的堆疊)
這篇文章我是 攢了好久 沒寫了,看了這篇文章好,我覺得可以幫助大家更容易瞭解lua的執行原理,與呼叫方法,若有錯誤也希望及時指正。希望可以幫助到你。(2.3中的Gif圖,可以生動的表現過程)
一、Lua虛擬機器的棧
1.1先簡單介紹下Lua虛擬機器的棧,如圖:
規則:
①若Lua虛擬機器堆疊裡有N個元素,則可以用 1 ~ N 從棧底向上索引,也可以用 -1 ~ -N 從棧頂向下索引,一般後者更加常用
②堆疊的每個元素可以為任意複雜的Lua資料型別,堆疊中沒有元素的空位,隱含為包含一個“空”型別資料
特性:
若有4個元素分別入棧,則:
①. 正數索引,棧底是1,然後一直到棧頂是逐漸+1,最後變成4(4大於1)
②. 負數索引,棧底是-4,然後一直到棧頂是逐漸+1,最後變成-1(-1大於-4)
索引相關:
①. 正數索引,不需要知道棧的大小,我們就能知道棧底在哪,棧底的索引永遠是1②. 負數索引,不需要知道棧的大小,我們就能知道棧頂在哪,棧頂的索引永遠是-1
二、執行原理例項
2.1程式碼演示
直接進入主題了,正如上節例項程式碼:
Lua程式碼:
--filename: luafile.lua
function LuaFunc()
return 1,2,3,4;
end
C++程式碼(其他程式碼工作原理一樣的這裡宿主語言使用C++好了):
/** * 函式名:Func * 作者:豬豬俠 * 日期:2014年11月13日20:46:54 **/ // Luatest.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> #include "lua.hpp" /** * 等價於: * extern "C" { * #include "lua.h" * #include "lualib.h" * #include "lauxlib.h" * } **/ int _tmain(int argc, _TCHAR* argv[]) { //①新建虛擬機器 lua_State *L = luaL_newstate(); //②載入庫 luaL_openlibs(L); //③這裡執行 test.lua Lua檔案 luaL_dofile(L, "luafile.lua"); //④重新設定棧底 lua_settop(L, 0); //⑤獲取 返回結果 lua_getglobal(L, "LuaFunc"); //⑥操作棧調回結果 lua_pcall(L, 0, 4, 0); printf("%s\n", lua_tostring(L, 1)); printf("%s\n", lua_tostring(L, 2)); printf("%s\n", lua_tostring(L, 3)); printf("%s\n", lua_tostring(L, 4)); //⑦一定記得關閉虛擬機器 lua_close(L); system("pause"); return 0; }
執行結果:
2.2程式碼分析
現在來開始分析過程:①~~④步
//①新建虛擬機器
lua_State *L = luaL_newstate();
//②載入庫
luaL_openlibs(L);
//③這裡執行 test.lua Lua檔案
luaL_dofile(L, "test.lua");
//④重新設定棧底
lua_settop(L, 0);
這裡註釋都寫 明白了吧,
①~③:建立棧,然後載入資源;
④:這個過程,是為了確認棧底是空的,以便後面的操作是按照順序入棧的且從1號棧位開始
//⑤獲取 返回結果 lua_getglobal(L, "LuaFunc");
⑤:這步開始 C++去訪問虛擬機器的 棧,送 “LuaFunc"入棧
//⑥操作棧調回結果
lua_pcall(L, 0, 4, 0);
⑥:(以下精華,望笑納)
1> C++告訴Lua虛擬機器(L),函式以輸入棧,函式傳入0個引數,會返回4個函式,不需要錯誤資訊(0)。(分別 對應上面四個引數)。(棧中一個元素:“LuaFunc" )
2> 這裡,C++(宿主語言)請求完畢了,虛擬機器(L)開始訪問棧,從棧中取出“LuaFunc"。(棧中無元素了:null)
3> 虛擬機器得到 “LuaFunc" 資訊送給 Lua程式(編譯器)。(棧中無元素了:null)
4> Lua程式 在 呼叫的 Lua檔案全域性表(Global table)中查詢“LuaFunc" ,並執行返回結果“1,2,3,4”。(棧中無元素了:null)
5> Lua程式得到返回結果“1,2,3,4” 將結果再壓入棧;壓入順序為,順序的,“1”先入棧底,“2”再入棧,以此類推。(棧中四個元素:1,2,3,4)(順序為棧底->棧頂)
6> 最後,C++(宿主語言)再去棧中讀取資料;這裡 lua_tostring(L,1)是讀取函式,不會改變棧內的結果的,所以當地⑥步執行完,棧中還是四個元素:1,2,3,4
提示:若使用lua_pop(L,1) 去操作的話,可以彈出指定的位置的棧內容
⑦這步也很重要,使用完虛擬機器,需要手動關閉的。
2.3完美動態展示:(製作這圖好辛苦啊,能給贊不???)
-------
敘述完畢,有何指教請指導啊。
謝謝支援哈。
受到的啟發地址:http://blog.csdn.net/musicvs/article/details/8445079