Lua学习 -- Lua调用原理(Lua堆栈)

原文: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 <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完美动态展示:

猜你喜欢

转载自blog.csdn.net/xueluowutong/article/details/86351923
LUA