原文:https://blog.csdn.net/zhuzhuyule/article/details/41086745
一、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
#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完美动态展示: