lua_pcall与lua_call之间的区别

定义:

  1. void lua_call (lua_State *L, int nargs, int nresults);
  2. int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

这两个api的前三个参数含义一样,只是lua_pcall在保护模式(protection mode)下调用函数。

在调用不出错的情况下,这两个函数的行为一模一样,但是lua_pcall有处理调用出错的能力,其处理方法主要取决于第四个参数 errfunc, 如果errfunc为0,则lua_pcall直接把错误信息通过lua_pushstring压栈,然后返回;然后errfunc不为0,则自动调用(L, errfunc)(errmsg),errmsg表示原始出错信息。

通常,使用errfunc输出一些额外的出错信息,比如stack traceback,这些信息在lua_pcall返回之后不能再得到。

lua_pcall的返回值:

  • LUA_ERRRUN: a runtime error.
  • LUA_ERRMEM: memory allocation error. For such errors, Lua does not call the error handler function.
  • LUA_ERRERR: error while running the error handler function.

下面给出了一个例子,来说明lua_pcall errfunc的工作原理:

luapcall.lua

  1. function printmsg()
  2. --故意制造调用出错
  3. printaa("hello world")
  4. end
  5. function errorhandle(str)
  6. return string.upper(str)
  7. end
  • 例1,errfunc = 0
  1. #include<iostream>
  2. #include<string>
  3. extern "C"{
  4. #include<lua.h>
  5. #include<lualib.h>
  6. #include<lauxlib.h>
  7. }
  8. using namespace std;
  9. int main(){
  10. lua_State *L = lua_open();
  11. luaopen_base(L);
  12. luaopen_table(L);
  13. luaopen_string(L);
  14. if(luaL_loadfile(L,"luapcall.lua")){
  15. cout << "open file error" << endl;
  16. return 1;
  17. }
  18. //载入执行程序
  19. if(lua_pcall(L,0,0,0)){
  20. cout << "function call error 0" << endl;
  21. }
  22. lua_getglobal(L, "errorhandle");
  23. lua_getglobal(L, "printmsg");
  24. // errfunc = 0,不处理错误信息
  25. if(lua_pcall(L, 0, 0, 0)){
  26. cout << lua_tostring(L, -1) << endl;
  27. cout << "function call error 1" << endl;
  28. }
  29. lua_close(L);
  30. return 0;
  31. }

执行结果:

  1. -bash-3.00$ ./a.out
  2. luapcall.lua:2: attempt to call global `printaa' (a nil value)
  3. function call error 1
  • 例2, errfunc != 0
  1. #include<iostream>
  2. #include<string>
  3. extern "C"{
  4. #include<lua.h>
  5. #include<lualib.h>
  6. #include<lauxlib.h>
  7. }
  8. using namespace std;
  9. int main(){
  10. lua_State *L = lua_open();
  11. luaopen_base(L);
  12. luaopen_table(L);
  13. luaopen_string(L);
  14. if(luaL_loadfile(L,"luapcall.lua")){
  15. cout << "open file error" << endl;
  16. return 1;
  17. }
  18. if(lua_pcall(L,0,0,0)){
  19. cout << "function call error 0" << endl;
  20. }
  21. lua_getglobal(L, "errorhandle");
  22. lua_getglobal(L, "printmsg");
  23. // 使用errorhandle函数处理错误信息
  24. if(lua_pcall(L, 0, 0, -2)){
  25. cout << lua_tostring(L, -1) << endl;
  26. cout << "function call error 1" << endl;
  27. }
  28. lua_close(L);
  29. return 0;
  30. }

执行结果:

  1. -bash-3.00$ ./a.out
  2. LUAPCALL.LUA:2: ATTEMPT TO CALL GLOBAL `PRINTAA' (A NIL VALUE)
  3. function call error 1

lua_pcall与lua_call之间的区别的更多相关文章

  1. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

  2. 你真的会玩SQL吗?EXISTS和IN之间的区别

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  3. [转]ExtJs基础--Html DOM、Ext Element及Component三者之间的区别

    要学习及应用好Ext框架,必须需要理解Html DOM.Ext Element及Component三者之间的区别. 每一个HTML页面都有一个层次分明的DOM树模型,浏览器中的所有内容都有相应的DOM ...

  4. iOS中assign,copy,retain之间的区别以及weak和strong的区别

    @property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Refe ...

  5. javascrip中parentNode和offsetParent之间的区别

    首先是 parentNode 属性,这个属性好理解,就是在 DOM 层次结构定义的上下级关系,如果元素A包含元素B,那么元素B就可以通过 parentElement 属性来获取元素A. 要明白 off ...

  6. 面试问题5:const 与 define 宏定义之间的区别

    问题描述:const 与 define 宏定义之间的区别 (1) 编译器处理方式不同     define宏是在预处理阶段展开:     const常量是编译运行阶段使用: (2) 类型和安全检查不同 ...

  7. 关于背景图相对父容器垂直居中问题 —— vertical-align 和 line-height 之间的区别

       html css <div class="register-wrapper"> <div class="register"> &l ...

  8. 转:WCF、WebAPI、WCFREST、WebService之间的区别

    WCF.WebAPI.WCFREST.WebService之间的区别   注明:转载 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API ...

  9. 深入理解 '0' "0" '\0' 0 之间的区别

    看来基础还是很重要的,基础不扎实就难以学好c语言,就别说写出高质量的c语言代码了.今天,我就被这个问题折磨的不行了,哈哈,不过现在终于明白了‘\0’ ,‘0’, “0” 之间的区别了.困惑和快乐与你分 ...

随机推荐

  1. 原生javascript实现文件异步上传

    效果图: 代码:(demo33.jsp) <%@ page contentType="text/html;charset=UTF-8" language="java ...

  2. C++逐行读取文本文件的正确做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 之前写了一个分析huson日志的控制台程序,其中涉及到C++逐行读取文本文件的做法,代码是这样写的: ifstream ...

  3. C# Distanct List集合

    简单一维集合的使用 List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 }; List<str ...

  4. PHP的分页

    页面的效果 页面的css @CHARSET "UTF-8"; *{ margin:0; padding:0; } body{ width:800px; margin:0 auto; ...

  5. 如何使用阿里云的yum源

    这里需要有网.因为我们需要下载会用到wget [root@localhost ~]# iptables -F[root@localhost ~]# systemctl stop firewalld[r ...

  6. 多进程Socket_Server

    import socketserverclass MyServer(socketserver.BaseRequestHandler): def handle(self): #继承BaseRequest ...

  7. Codeforces Round #506 (Div. 3) D-F

    Codeforces Round #506 (Div. 3) (中等难度) 自己的做题速度大概只尝试了D题,不过TLE D. Concatenated Multiples 题意 数组a[],长度n,给 ...

  8. 深度学习之入门Pytorch(1)------基础

    目录: Pytorch数据类型:Tensor与Storage 创建张量 tensor与numpy数组之间的转换 索引.连接.切片等 Tensor操作[add,数学运算,转置等] GPU加速 自动求导: ...

  9. Build rpm example:zram

    rpmbuild #ll zram-1.0.0 total 32 -rw-r--r-- 1 root root 948 Aug 21 16:44 Makefile -rw-r--r-- 1 root ...

  10. 【安装配置Redis】

    目录 安装 配置 Redis官网:https://redis.io Redis是完全开源免费的,遵守BSD协议. Redis是一个高性能的key-value数据库. @ *** Redis具有以下特点 ...