• lua_pcall与lua_call之间的区别


    lua_pcall与lua_call之间的区别

    定义:

    void lua_call (lua_State *L, int nargs, int nresults);
    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

    function printmsg()
        --故意制造调用出错
        printaa("hello world")
    end
    
    function errorhandle(str)
        return string.upper(str)
    end
    
    • 例1,errfunc = 0
    #include<iostream>
    #include<string>
    extern "C"{
        #include<lua.h>
        #include<lualib.h>
        #include<lauxlib.h>
    }
    using namespace std;
    
    int main(){
        lua_State *L = lua_open();
        luaopen_base(L);
        luaopen_table(L);
        luaopen_string(L);
    
        if(luaL_loadfile(L,"luapcall.lua")){
            cout << "open file error" << endl;
            return 1;
        }
        //载入执行程序
        if(lua_pcall(L,0,0,0)){
            cout << "function call error 0" << endl;
        }
    
        lua_getglobal(L, "errorhandle");
        lua_getglobal(L, "printmsg");
        
        // errfunc = 0,不处理错误信息
        if(lua_pcall(L, 0, 0, 0)){
            cout << lua_tostring(L, -1) << endl;
            cout << "function call error 1" << endl;
        }
    
        lua_close(L);
    
        return 0;
    }
    

    执行结果:

    -bash-3.00$ ./a.out
    luapcall.lua:2: attempt to call global `printaa' (a nil value)
    function call error 1
    
    • 例2, errfunc != 0
    #include<iostream>
    #include<string>
    extern "C"{
        #include<lua.h>
        #include<lualib.h>
        #include<lauxlib.h>
    }
    using namespace std;
    
    int main(){
        lua_State *L = lua_open();
        luaopen_base(L);
        luaopen_table(L);
        luaopen_string(L);
    
        if(luaL_loadfile(L,"luapcall.lua")){
            cout << "open file error" << endl;
            return 1;
        }
        if(lua_pcall(L,0,0,0)){
            cout << "function call error 0" << endl;
        }
    
        lua_getglobal(L, "errorhandle");
        lua_getglobal(L, "printmsg");
        // 使用errorhandle函数处理错误信息
        if(lua_pcall(L, 0, 0, -2)){
            cout << lua_tostring(L, -1) << endl;
            cout << "function call error 1" << endl;
        }
    
        lua_close(L);
    
        return 0;
    }
    

    执行结果:

    -bash-3.00$ ./a.out
    LUAPCALL.LUA:2: ATTEMPT TO CALL GLOBAL `PRINTAA' (A NIL VALUE)
    function call error 1
    
  • 相关阅读:
    mysql 导入CSV数据 [转]
    Linux用户态程序计时方式详解[转]
    [转] Bash脚本:怎样一行行地读文件(最好和最坏的方法)
    第二次作业
    软件工程原理与方法 第一次作业
    2017-02-19,周日整理
    2017-02-12,周日整理
    cnblogs,第一次博客纪念。
    堆和栈的区别(转过无数次的文章)
    Flash Player版本相关问题
  • 原文地址:https://www.cnblogs.com/keviwu/p/5877883.html
Copyright © 2020-2023  润新知