Lua 和 C 交互中虚拟栈的操作
Lua 和 C 交互中虚拟栈的操作
/* 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 = ;
int top = lua_gettop(L); // 获取栈中元素个数
std::cout << "lua stack value count: " << top << std::endl;
for (i = ; i <= top; ++i) // 遍历栈中每一个元素 // 栈底的序号为1, 依次递增. 栈顶的序号始终为-1
{
int t = lua_type(L, i); // 获取元素的类型
switch (t)
{
case LUA_TSTRING: // strings
std::cout << lua_tostring(L, i);
break; case LUA_TBOOLEAN: // bool
std::cout << (lua_toboolean(L, i) != ? "true" : "false");
break; case LUA_TNUMBER: // number
std::cout << lua_tonumber(L, i);
break; default: // other values
std::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, ); // true
lua_pushnumber(L, ); //
lua_pushnil(L); // nil
lua_pushstring(L, "hello"); // "hello"
stackDump(L); // true 10 nil 'hello' lua_pushvalue(L, -); // 将索引-4处的值的副本入栈
stackDump(L); // true 10 nil 'hello' true lua_replace(L, ); // 将栈顶元素移动到索引3处,并覆盖原先的元素
stackDump(L); // true 10 true 'hello' lua_settop(L, ); // 将栈顶设置为索引6处,多出来的新元素被赋值为"nil"
stackDump(L); // true 10 true 'hello' nil nil lua_remove(L, -); // 移除索引-3处的元素,其上所有元素下移
stackDump(L); // true 10 true nil nil lua_settop(L, -); // 将栈顶设置为索引-5处
stackDump(L); // true lua_close(L); // 关闭Lua状态机 std::cout << "..." << std::endl;
system("pause");
return ;
}
Lua 和 C 交互中虚拟栈的操作的更多相关文章
- Lua和C++交互详细总结
转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信 ...
- [转载]Lua和C++交互详细总结
原文请看:Lua和C++交互详细总结 转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. ...
- lua中得栈
如果你看了LUA的文档,那么就应该很清楚LUA与C交互数据时都是用到LUA中所谓的stack.那么当我调用lua_open函数之后栈是什么样的呢?空的(luaopen_base等会往栈上加进一些东西) ...
- Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...
- Lua和C++交互 学习记录之二:栈操作
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- Lua的函数调用和协程中,栈的变化情况
Lua的函数调用和协程中,栈的变化情况 1. lua_call / lua_pcall 对于这两个函数,对栈底是没有影响的--调用的时候,参数会被从栈中移除,当函数返 回的时候,其返回值会从函数处 ...
- lua与C交互 具体
什么样类型的函数可以被Lua调用 typedef int (*lua_CFunction) (lua_State *L); 符合类型的函数怎样处理后才可以被Lua调用 使用lua_register或者 ...
- Lua和C交互的简易教程
转载请标明出处:http://blog.csdn.net/shensky711/article/details/52458051 本文出自: [HansChen的博客] Lua栈 要理解Lua和C++ ...
- C与Lua互相调用的时候,栈变化分析
1 C调用Lua函数的堆栈变化 例子 Lua文件中的函数 function testNewCounter2() return "第四个结果" end C中的例子 void t_n ...
随机推荐
- Openlayers系列(一)关于地图投影的理解
背景 近期开发以MongoDB为基础的分布式地理数据管理平台系统,被要求做一个简单的demo给客户进行演示.于是笔者便打算向数据库中存储一部分瓦片数据,写一个简单的存取服务器,使用Openlayers ...
- 什么是PWM信号
PWM信号脉宽调制PWM是开关型稳压电源中的术语.这是按稳压的控制方式分类的,除了PWM型,还有PFM型和PWM.PFM混合型.脉宽宽度调制式(PWM)开关型稳压电路是在控制电路输出频率不变的情况下, ...
- vue实例讲解之axios的使用
本篇来讲解一下axios插件的使用,axios是用来做数据交互的插件. 这篇将基于vue实例讲解之vue-router的使用这个项目的源码进行拓展. axios的使用步骤: 1.安装axios npm ...
- base64码转图片
1将图片转换为Base64编码,可以让你很方便地在没有上传文件的条件下将图片插入其它的网页.编辑器中. 这对于一些小的图片是极为方便的,因为你不需要再去寻找一个保存图片的地方. 2.假定生成的代码为& ...
- 化繁为简 经典的汉诺塔递归问题 in Java
问题描述 在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑 ...
- 18.Llinux-触摸屏驱动(详解)
本节的触摸屏驱动也是使用之前的输入子系统 1.先来回忆之前第12节分析的输入子系统 其中输入子系统层次如下图所示, 其中事件处理层的函数都是通过input_register_handler()函数注册 ...
- http://codeforces.com/contest/828
哇这是我打的第一场cf,第一题都wa了无数次,然后第二题差几分钟交 ,第二天一交就AC了内心是崩溃的.果然我还是太菜l.... A. Restaurant Tables time limit per ...
- 混合高斯模型(Mixtures of Gaussians)和EM算法
这篇讨论使用期望最大化算法(Expectation-Maximization)来进行密度估计(density estimation). 与k-means一样,给定的训练样本是,我们将隐含类别标签用表示 ...
- Ubuntu中MongoDB安装
在Ubuntu中MongoDB有时候启动不起来,可以参考以下方法从新安装: 1.导入包管理系统使用的公钥 Ubuntu 的软件包管理工具(即dpkg和APT)要求软件包的发布者通过GPG密钥签名来确保 ...
- 【JAVA零基础入门系列】Day4 变量与常量
这一篇主要讲解Java中的变量,什么是变量,变量的作用以及如何声明,使用变量. 那么什么是变量?对于初学者而言,可以将变量理解为盒子,这些盒子可以用来存放数据,不同类型的数据需要放在对应类型的盒子里. ...