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代码:

[sql]  view plain  copy
  1. --filename: luafile.lua  
  2.   
  3. function LuaFunc()  
  4.     return 1,2,3,4;  
  5. end  

C++代码(其他代码工作原理一样的这里宿主语言使用C++好了):

[cpp]  view plain  copy
  1. /** 
  2. * 函数名:Func 
  3. * 作者:猪猪侠 
  4. * 日期:2014年11月13日20:46:54 
  5. **/  
  6.   
  7. // Luatest.cpp : 定义控制台应用程序的入口点。    
  8. //    
  9.   
  10. #include "stdafx.h"    
  11. #include <iostream>    
  12. #include "lua.hpp"    
  13. /** 
  14. * 等价于: 
  15. * extern "C" { 
  16. * #include "lua.h" 
  17. * #include "lualib.h" 
  18. * #include "lauxlib.h" 
  19. * } 
  20. **/  
  21.   
  22.   
  23. int _tmain(int argc, _TCHAR* argv[])  
  24. {  
  25.     //①新建虚拟机    
  26.     lua_State *L = luaL_newstate();  
  27.     //②载入库    
  28.     luaL_openlibs(L);  
  29.   
  30.     //③这里执行 test.lua  Lua文件    
  31.     luaL_dofile(L, "luafile.lua");  
  32.     //④重新设置栈底  
  33.     lua_settop(L, 0);  
  34.   
  35.     //⑤获取 返回结果    
  36.     lua_getglobal(L, "LuaFunc");  
  37.   
  38.     //⑥操作栈调回结果  
  39.     lua_pcall(L, 0, 4, 0);  
  40.     printf("%s\n", lua_tostring(L, 1));  
  41.     printf("%s\n", lua_tostring(L, 2));  
  42.     printf("%s\n", lua_tostring(L, 3));  
  43.     printf("%s\n", lua_tostring(L, 4));  
  44.   
  45.     //⑦一定记得关闭虚拟机    
  46.     lua_close(L);  
  47.   
  48.     system("pause");  
  49.     return 0;  
  50. }  

执行结果:



2.2代码分析

现在来开始分析过程:①~~④步

[cpp]  view plain  copy
  1. //①新建虚拟机    
  2. lua_State *L = luaL_newstate();     
  3. //②载入库    
  4. luaL_openlibs(L);    
  5.   
  6. //③这里执行 test.lua  Lua文件    
  7. luaL_dofile(L, "test.lua");   
  8. //④重新设置栈底  
  9. lua_settop(L, 0);  

这里注释都写 明白了吧,

①~③:建立栈,然后载入资源;

④:这个过程,是为了确认栈底空的,以便后面的操作是按照顺序入栈从1号栈位开始

[cpp]  view plain  copy
  1. //⑤获取 返回结果    
  2. lua_getglobal(L, "LuaFunc");  

⑤:这步开始 C++去访问虚拟机的 栈,送 “LuaFunc"入栈

[cpp]  view plain  copy
  1. //⑥操作栈调回结果  
  2. 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

猜你喜欢

转载自blog.csdn.net/jinxinliu1/article/details/79206055
LUA