我正在开发一个使用Lua编写脚本的程序,有时它会崩溃.使用GDB我认为我发现了问题,但我不知道它是否解决了它,因为段错误只会偶尔发生.所以,旧代码是这样的:
void Call(std::string func){
lua_getglobal(L, func.c_str()); //This is the line GDB mentioned in a backtrace
if( lua_isfunction(L,lua_gettop(L)) ) {
int err = lua_pcall(L, 0, 0,0 );
if(err != 0){
std::cout << "Lua error: " << luaL_checkstring(L, -1) << std::endl;
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,这个函数每秒会被调用几次,但它需要调用的函数并不总是被定义,所以我认为堆栈会溢出.我添加了以下行:
lua_pop(L,lua_gettop(L));
Run Code Online (Sandbox Code Playgroud)
并且不再发生段错误了.这可能是问题吗?
使用lua_gettop(L)
作为参数lua_pop
将清除整个Lua API堆栈(它相当于lua_settop(0)
),这可能不是您想要的.但确实你的问题是lua_getglobal
总是推动一些东西; 如果不存在具有给定名称的全局,则它会推送nil
,就像等效的Lua表达式一样.但是,lua_pcall
弹出函数和所有参数(如果有的话;在您的情况下,您指定为零),因此如果函数存在,您将不会遇到问题.你应该做的是增加外部的lua_pop(L, 1)
一个else
条款if
.这样,您的功能将始终保持平衡(即保持堆栈不变).
你可以在Lua手册中看到这些东西:对于每个函数,它都在描述中拼写出来,并在函数原型旁边的括号中用灰色表示.例如,lua_getglobal
有[-0,+ 1,e]意味着它不会弹出任何元素,并且(总是)推送一个元素(并且e意味着它可能导致错误).