Lua注册表与轻用户数据和引用有什么区别?

时间:2016-10-22 07:48:00

标签: c++ c lua lua-api lua-c++-connection

因此,使用Lua C API,您可以在注册表中保存Lua值并在以后检索它。有不同的方法,你可以创建一个变量,并使用它的指针作为注册表中的键,因为它始终是唯一的。您可以将指针推送为轻用户数据。

您还可以使用LuaL_ref(L, LUA_REGISTRYINDEX)创建参考。一个优于另一个的优势是什么?何时使用引用以及何时使用指针?

还有引用,因为它被称为引用,如果Lua垃圾收集器收集Lua值,注册表中的值是nil吗?如果Lua更新了Lua值,注册表中的值也会改变吗?

2 个答案:

答案 0 :(得分:1)

Lua注册表只是另一个lua表,可通过预定义的“特殊”索引轻松访问。我想你不需要解释Lua表与light userdata的不同之处 只要您可以在C / C ++端存储该密钥,您将如何索引注册表表并不重要。为方便起见,已有函数(luaL_ref / luaL_unref)为您提供易于存储和移动的整数键。

关于垃圾收集 - 规则始终相同。只要将值存储在未标记为弱表的表中(注册表不是弱表),该值就不会被清除。您必须从注册表中明确删除值。

更改值将遵循正常的Lua规则。为某个变量分配新的不可变值不会更改存储在注册表中的值,即注册表不会跟踪某些变量的更新。但是改变可变值(表等)的内容是可以的,因为注册表和变量将引用相同的值。

答案 1 :(得分:1)

除了之前的回答:

Lua lightuserdatauserdata

之间的差异

lightuserdata是一种特殊的Lua类型(以及nilbooleannumberstringtable,{{1等)包含C指针。而已。您无法将metatable分配给thread。相反,您可以将metatable分配给lightuserdata类型。例如,请参阅Lua File operations,其中文件句柄为userdata的方法。 userdata f为f:read("*all"),该命令相当于userdata

使用整数或C指针

索引f.read(f, "*all")

在注册表中广泛使用了两种方法。

  1. 使用LUA_REGISTRYINDEX创建对Lua值的新引用,并将返回整数值存储在代码中的某处。即要访问Lua值,您需要读取包含luaL_ref引用和索引注册表的C变量,其中该值是整数值。 lua_rawgeti(L, LUA_REGISTRYINDEX, i)也可以,但不要尝试使用此方法重写为零值!

  2. 您创建静态C变量lua_rawseti(L, LUA_REGISTRYINDEX, i),然后使用static int myvar;lua_rawgetp(L, LUA_REGISTRYINDEX, p)直接操作存储的Lua值。

  3. 不幸的是,我无法比较两种方法的表现。我认为它们几乎是一样的。