因此,使用Lua C API,您可以在注册表中保存Lua值并在以后检索它。有不同的方法,你可以创建一个变量,并使用它的指针作为注册表中的键,因为它始终是唯一的。您可以将指针推送为轻用户数据。
您还可以使用LuaL_ref(L, LUA_REGISTRYINDEX)
创建参考。一个优于另一个的优势是什么?何时使用引用以及何时使用指针?
还有引用,因为它被称为引用,如果Lua垃圾收集器收集Lua值,注册表中的值是nil
吗?如果Lua更新了Lua值,注册表中的值也会改变吗?
答案 0 :(得分:1)
Lua注册表只是另一个lua表,可通过预定义的“特殊”索引轻松访问。我想你不需要解释Lua表与light userdata的不同之处 只要您可以在C / C ++端存储该密钥,您将如何索引注册表表并不重要。为方便起见,已有函数(luaL_ref / luaL_unref)为您提供易于存储和移动的整数键。
关于垃圾收集 - 规则始终相同。只要将值存储在未标记为弱表的表中(注册表不是弱表),该值就不会被清除。您必须从注册表中明确删除值。
更改值将遵循正常的Lua规则。为某个变量分配新的不可变值不会更改存储在注册表中的值,即注册表不会跟踪某些变量的更新。但是改变可变值(表等)的内容是可以的,因为注册表和变量将引用相同的值。
答案 1 :(得分:1)
除了之前的回答:
lightuserdata
和userdata
lightuserdata
是一种特殊的Lua类型(以及nil
,boolean
,number
,string
,table
,{{1等)包含C指针。而已。您无法将metatable分配给thread
。相反,您可以将metatable分配给lightuserdata
类型。例如,请参阅Lua File operations,其中文件句柄为userdata
的方法。 userdata
f为f:read("*all")
,该命令相当于userdata
f.read(f, "*all")
在注册表中广泛使用了两种方法。
使用LUA_REGISTRYINDEX
创建对Lua值的新引用,并将返回整数值存储在代码中的某处。即要访问Lua值,您需要读取包含luaL_ref
引用和索引注册表的C变量,其中该值是整数值。 lua_rawgeti(L, LUA_REGISTRYINDEX, i)
也可以,但不要尝试使用此方法重写为零值!
您创建静态C变量lua_rawseti(L, LUA_REGISTRYINDEX, i)
,然后使用static int myvar;
和lua_rawgetp(L, LUA_REGISTRYINDEX, p)
直接操作存储的Lua值。
不幸的是,我无法比较两种方法的表现。我认为它们几乎是一样的。