前面说过,在我们的项目中使用的是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,关于这个还在研究中。。。
