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
原文地址:https://www.cnblogs.com/keviwu/p/5877883.html