這篇文章我是 攢了好久 沒寫了,看了這篇文章好,我覺得可以幫助大家更容易瞭解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