前面说过,在我们的项目中使用的是luabind。
调用lua函数的接口是:call_function<bool>(m_lua, func_name, player);
如果func出错了,lua会抛出异常,c++程序捕捉到后程序可能会崩掉(就看有没有对异常的抛出做反映),所以光写call_function这个函数的话是看不到错误信息的,我们需要把异常捕捉出来。
try {
bool ret = call_function<bool>(m_lua, func_name, player);
return ret;
} catch(luabind::error& e) {
ERROR_LOG("AI[%u] throw error: err_msg[%s]", player->id, lua_tostring(m_lua, -1));
return false;
}
这样我们就能从堆栈中获取抛出的异常,同时程序也不会因此而崩掉!
但是这样显示的异常可能还不够完整,我们又是想知道出错在哪个lua脚本的哪行代码上,这就需要使用lua_Debug来调用信息。
通过查阅luabind和lua的参考手册(以后要养成这样的习惯,不能全依赖于google)发现,在call_function的调用抛出异常以后,这个function已经从stack中删除,所以使用lua_getstack会失败。luabind手册中点明可以通过luabind::set_pcall_callback这个函数来自定义lua_pcall的错误处理函数。
因此:
自定义错误处理函数:
int pcall_callback_err_fun(lua_State* L)
{
lua_Debug debug;
lua_getstack(L, 2, &debug);
lua_getinfo(L, "Sln", &debug);
std::string err = lua_tostring(L, -1);
lua_pop(L, 1);
std::stringstream msg;
msg << debug.short_src << ":line " << debug.currentline;
if (debug.name != 0) {
msg << "(" << debug.namewhat << " " << debug.name << ")";
}
msg << " [" << err << "]";
lua_pushstring(L, msg.str().c_str());
return 1;
}
绑定函数:
luabind::set_pcall_callback(pcall_callback_err_fun);
注意的是:lua_getstack(L, 2, &debug)中参数level需要设置为2,关于这个还在研究中。。。