你打电话lua_pop()
从 Lua 堆栈中删除项目。对于简单的函数,这可能完全没有必要,因为核心将清理堆栈作为处理返回值的一部分。
对于更复杂的函数,尤其是调用 Lua 的 C 代码,您通常需要从堆栈中弹出内容以防止堆栈无限增长。
The lua_getglobal()
函数在调用时向堆栈添加一项,即nil
如果全局不存在或指定全局变量的值。只要该值存在,在堆栈上保存该值的副本就可以保护它免受垃圾收集器的影响。只要检索它的 C 代码正在使用该值,就需要保留在堆栈上,因为如果修改全局值,堆栈上的副本可能是唯一剩余的引用。
所以使用全局的一般模式是这样的:
void doMyEvent(lua_State *L) {
lua_getglobal(L, "MyEvent");
lua_call(L, 0, 0); /* pops the function and 0 parameters, pushes 0 results */
}
double getGlobalDouble(lua_State *L, const char *name) {
double d;
lua_getglobal(L,name);
d = lua_tonumber(L,1); /* extracts the value, leaves stack unchanged */
lua_pop(L,1); /* pop the value to leave stack balanced */
return d;
}
char *copyGlobalString(lua_State *L, const char *name) {
char *s = NULL;
lua_getglobal(L,name);
if (!lua_isnil(L,-1))
s = strdup(lua_tostring(L,-1));
lua_pop(L,1);
return s;
}
在最后一个示例中,我小心地复制了字符串的内容,因为返回的指针lua_tostring()
仅当该值保留在堆栈中时才保证有效。要求调用者copyGlobalString()
负责打电话free()
later.
另请注意,最新版本的Lua手册每个函数都包含一个符号,用于标识消耗的堆栈条目数和推送的数。这有助于避免意外的堆栈增长。