Lua registry with light userdata 和 references 有什么区别?

What is the difference between Lua registry with light userdata and references?

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

您还可以使用 LuaL_ref(L, LUA_REGISTRYINDEX) 创建引用。一个比另一个有什么优势?什么时候用引用,什么时候用指针?

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

Lua 注册表只是另一个 lua table,可通过预定义的 "special" 索引轻松访问。我想您不需要解释 Lua table 与轻型用户数据有何不同。
如何索引注册表 table 并不重要,只要您可以将该密钥存储在 C/C++ 端即可。为了您的方便,已经有函数 (luaL_ref/luaL_unref) 为您提供易于存储和移动的整数键。

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

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

除了之前的回答:

Lua lightuserdatauserdata

之间的区别

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

用整数或 C 指针索引 LUA_REGISTRYINDEX

注册表中广泛使用的方法有两种table。

  1. 使用 luaL_ref 创建对 Lua 值的新引用,并将 return 整数值存储在代码中的某处。 IE。要访问 Lua 值,您需要读取包含引用和索引注册表 table 和 lua_rawgeti(L, LUA_REGISTRYINDEX, i) 的 C 变量,该整数值在哪里。 lua_rawseti(L, LUA_REGISTRYINDEX, i)也是可以的,但是不要尝试用这种方法重写成nil值!

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

遗憾的是,我无法比较这两种方法的性能。我觉得他们差不多。