int lua_pcall(lua_State *L, int nargs, int nresults, int msgh)
 * 以保护模式调用具有"nargs"个参数,"nresults"个返回值得函数。函数在第一个参数的前一个位置。
 * 保护模式指的是当调用出错时不会报错,而是返回一个错误码同时将错误信息入栈。
 * 当调用成功时,函数返回0。将函数名以及参数出栈,之后将函数的返回值入栈。
 * 无论函数返回多少个返回值,Lua会调整为你需要的数量,忽略多余的或者将不够的补为"nil"。
 * 当调用出错时,函数返回非0值。将函数名以及参数出栈,
 * 以错误信息作为参数,执行虚拟栈中索引"msgh"处的出错处理函数,
 * 将出错处理函数的返回值作为"lua_pcall"的返回值入栈。
 * "msgh"为0代表没有错误处理函数,错误处理函数必须要在被调用函数和其参数入栈之前入栈。
 * 典型的用法中,错误处理函数被用来给错误消息加上更多的调试信息,比如栈跟踪信息。
 * 这些信息在"lua_pcall"返回后,由于栈已经展开,所以收集不到了。
 * lua_pcall 函数会返回下列常数(定义在"lua.h"内)中的一个:
   LUA_OK (0): 成功。
   LUA_ERRRUN: 运行时错误(一般错误)。
   LUA_ERRMEM: 内存分配错误(此种情况,Lua不会调用错误处理函数)。
   LUA_ERRERR: 在运行错误处理函数时发生的错误(此种情况,Lua不会再次调用错误处理函数)。
   LUA_ERRGCMM: 在运行"__gc"元方法时发生的错误(这个错误和被调用的函数无关。)。

#include <iostream>
#include <lua.hpp>/* // lua.hpp 中的内容
// lua 是以ANSI C编写的, 所以在C++中使用必须加上 extern "C" { } , 显示的告诉编译器以C的方式编译代码
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
*//** Lua中的字符串可以不以'\0'作为结束符。这样,字符串中可以包含任意的二进制(甚至是'\0'),字符串的长度由明确的长度指定* 在lua_pushlstring()、lua_pushliteral()以及lua_pushstring()中,Lua不保存字符串(变量)指针。因此当这些函数返回时,你就可以修改你的字符串了* 遍历一个”table”时,不要将lua_tolstring()作用在”key”上,这样会导致lua_next()无法正常运行** 对于入栈是否有栈空间的情况,你需要自己判断,别忘了现在你是一个C程序员。当Lua启动或者任何Lua调用C的时候,虚拟栈中至少有20个空间(在”lua.h”中LUA_MINSTACK定义),这对于一般情况下够用了,所以一般不用考虑。但有时候确实需要更多的栈空间(比如调用一个不定参数的函数),此时你需要使用lua_checkstack检查栈空间的情况** int lua_checkstack(lua_State *L, int sz)* 确保堆栈上至少有"n"个额外空位。如果不能把堆栈扩展到相应的尺寸,函数返回"false"。* 失败的原因包括将把栈扩展到比固定最大尺寸还大(至少是几千个元素)或分配内存失败。* 这个函数永远不会缩小堆栈,如果堆栈已经比需要的大了,那么就保持原样。** 在平常的编码中,对于执行失败时会返回0的lua_to*()类别的函数,我们最好先使用lua_is*()类别的函数判断参数的类型,之后再使用lua_to*()类别的函数对参数进行转换;而对于执行失败时会返回NULL的lua_to*()类别的函数,我们可以直接使用lua_to*()类别的函数直接对参数进行转换,判断函数的返回值非NULL与否,就能判断转换是否成功** lua_pop()就是通过lua_settop()实现的(在”lua.h”中定义)* #define lua_pop(L,n) lua_settop(L, -(n)-1)** 以下操作对于虚拟栈没有任何影响, 栈中元素个数还是一样多* lua_settop(L, -1);     // set top to its current value* lua_insert(L, -1);    // move top element to the top* lua_replace(L, -1);    // replace top element by the top element**/static void stackDump(lua_State * L)
{int i = 0;int top = lua_gettop(L); // 获取栈中元素个数std::cout << "lua stack value count: " << top << std::endl;for (i = 1; i <= top; ++i) // 遍历栈中每一个元素 // 栈底的序号为1, 依次递增. 栈顶的序号始终为-1{int t = lua_type(L, i); // 获取元素的类型switch (t){case LUA_TSTRING: // stringsstd::cout << lua_tostring(L, i);break;case LUA_TBOOLEAN: // boolstd::cout << (lua_toboolean(L, i) != 0 ? "true" : "false");break;case LUA_TNUMBER: // numberstd::cout << lua_tonumber(L, i);break;default: // other valuesstd::cout << lua_typename(L, t); // 将宏定义的类型码转换为类型名称break;}std::cout << " ";}std::cout << std::endl;
}int main()
{lua_State * L = luaL_newstate(); // 创建Lua虚拟机luaL_openlibs(L); // 打开Lua状态机"L"中的所有Lua标准库// 向虚拟栈中压入值lua_pushboolean(L, 1);  // truelua_pushnumber(L, 10); // 10lua_pushnil(L); // nillua_pushstring(L, "hello"); // "hello"stackDump(L); // true  10  nil  'hello'lua_pushvalue(L, -4); // 将索引-4处的值的副本入栈stackDump(L); // true  10  nil  'hello'  truelua_replace(L, 3); // 将栈顶元素移动到索引3处,并覆盖原先的元素stackDump(L); // true  10  true  'hello'lua_settop(L, 6); // 将栈顶设置为索引6处,多出来的新元素被赋值为"nil"stackDump(L); // true  10  true  'hello'  nil  nillua_remove(L, -3); // 移除索引-3处的元素,其上所有元素下移stackDump(L); // true  10  true  nil  nillua_settop(L, -5); // 将栈顶设置为索引-5处stackDump(L); // truelua_close(L); // 关闭Lua状态机std::cout << "..." << std::endl;system("pause");return 0;
}

Lua 和 C 交互中虚拟栈的操作和遍历相关推荐

  1. Lua和C++交互总结(很详细)

    出处:http://blog.csdn.net/shun_fzll/article/details/39120965 一.lua堆栈 要理解lua和c++交互,首先要理解lua堆栈. 简单来说,Lua ...

  2. [转载]Lua和C++交互详细总结

    原文请看:Lua和C++交互详细总结 转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. ...

  3. Lua和C++交互详细总结

    一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈.栈的特点是先进后出. 在Lua中,Lua堆栈就是一个struct ...

  4. Lua和C++交互详细总结【转载】

    [转] 原文 已丢失转自 链接 .备份.侵删 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈.栈的特点是先进后出 ...

  5. 常见Java面试题之解释内存中的栈、堆和静态区用法

    栈(stack).堆(heap)和静态区(static area)的用法区别 * 通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间: * 通过new关 ...

  6. Java - 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 通常我们定义一个基本数据类型的变量,一个对象的引用, ...

  7. lua 和 c交互详解(一)

    lua与c之间交互是通过"lua堆栈"通信的.不管是lua调用c还是c调用lua,都是通过操作lua堆栈实现的.顾名思义,lua堆栈也满足后进先出的特点,入栈/出栈都围绕栈顶进行的 ...

  8. lua与c#交互篇 | 合理用好lua+unity,更省性能的方案整理

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  9. Lua与c++交互实战基础篇-夏曹俊-专题视频课程

    Lua与c++交互实战基础篇-10018人已学习 课程介绍         本课程从实战角度讲解了流行的高性能脚本Lua与c++的联合开发,这套方案已经被大量的对性能由要求的系统使用,成为了高性能脚本 ...

最新文章

  1. Windows ThinPC 最终版已 RTM
  2. python创建项目包
  3. C语言实现镜子mirror算法(附完整源码)
  4. Error(6,35)java: 程序包 不存在,解决办法
  5. MacBook刷机勘错篇
  6. Java 8 Stream Api 中的 peek、map、foreach区别
  7. echarts柱状图 与轴不重叠_如何让柱状图柱子不挨着坐标轴,就像图片这样
  8. 路由表(FIB)详解
  9. 服务器间 存活状态,Shell脚本监控LVS后台服务器存活状态
  10. 图例放在图的外面_手把手教你绘制多个置信区间的森林图
  11. Java多线程-join方法
  12. python采用面向对象编程模式吗_python面向对象编程练习
  13. 使用C做的移动方块游戏
  14. 下一代 Web 应用模型 — Progressive Web App
  15. CentOS的U盘安装,vim主题设置,笔记本合盖不休眠
  16. AWTRIX像素屏时钟搭建
  17. BUUCTF rsarsa
  18. 数据结构-树与二叉树-思维导图+小结
  19. PS中“曲线”【ctrl+M】的作用【加强对曲线的使用】
  20. 主流分布式文件系统对比:区块链分布式技术引发云存储革命?HDFS,GFS,GPFS,FusionStorage,IPFS

热门文章

  1. Spring集成web环境步骤
  2. 编写网关过滤器统一校验登录状态
  3. 定时任务四种实现方式
  4. Java-Calendar
  5. 201029阶段二Linux动态库、makefile
  6. C#设计模式——生成器模式(Builder Pattern)
  7. ActivityInfo taskAffinity
  8. 柯南君:看大数据时代下的IT架构(4)消息队列之RabbitMQ--案例(Helloword起航)...
  9. python交互模式设置及VIM的tab补齐
  10. vsftpd虚拟用户和本地用户不能共存的解决方法