Lua初学者(四)--Lua调用原理展示(lua的堆栈)

概念理解 同时被 2 个专栏收录
4 篇文章 0 订阅
6 篇文章 0 订阅

这篇文章我是 攒了好久 没写了,看了这篇文章好,我觉得可以帮助大家更容易了解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


©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值