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