1. 程式人生 > >Lua初學者(四)--Lua呼叫原理展示(lua的堆疊)

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