Lua和C API是通过一个虚拟栈结构lua_State
交互的。关于这个虚拟栈,Lua官方手册给的提示并不多。
首先,lua栈上的对象和值是受到GC控制的。因此这样的代码可能存在一些问题:
lua_State* xL=lua_newthread(L);
lua_pop(L,1)
// work with xL...
在这里,lua_newthread
执行后,会有一个新thread
被放到L
上,然后将其返回为xL
。此时如果将其从栈上弹出,这个对象虽然在C层上被持有着,但是在Lua层中已经不存在了(消失了),因此GC是有权利进行回收的。这会导致xL
变成一个失效变量,以至于程序崩溃。
类似的,如果将一个string
放到栈上,然后pop掉,之前lua_tostring
返回的字符串指针也有可能因为对象已经被GC而失效。(即使程序仍然运行在C API层)
对于这种情况,如果想在C函数返回之后也能有效的持有变量,又不想设置成全局变量,可以使用luaL_ref
将数据存到Registry
表中,然后存储返回的int
(或者,从Lua角度上讲,reference
引用)。用法如下: