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 lightuserdata
和 userdata
之间的区别
lightuserdata
是一种特殊的 Lua 类型(以及 nil
、boolean
、number
、string
、table
, thread
等) 包含 C 指针。而已。您不能将 metatable 分配给 lightuserdata
。相反,您可以将 metatable 分配给 userdata
类型。例如,请参阅 Lua File operations,其中文件句柄是 userdata
和方法。 f:read("*all")
f is userdata
该命令等同于f.read(f, "*all")
用整数或 C 指针索引 LUA_REGISTRYINDEX
注册表中广泛使用的方法有两种table。
使用 luaL_ref
创建对 Lua 值的新引用,并将 return 整数值存储在代码中的某处。 IE。要访问 Lua 值,您需要读取包含引用和索引注册表 table 和 lua_rawgeti(L, LUA_REGISTRYINDEX, i)
的 C 变量,该整数值在哪里。 lua_rawseti(L, LUA_REGISTRYINDEX, i)
也是可以的,但是不要尝试用这种方法重写成nil值!
您创建了一个静态 C 变量 static int myvar;
,然后使用 lua_rawgetp(L, LUA_REGISTRYINDEX, &myvar)
和 lua_rawsetp(L, LUA_REGISTRYINDEX, &myvar)
直接操作存储的 Lua 值。
遗憾的是,我无法比较这两种方法的性能。我觉得他们差不多。
因此,使用 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 lightuserdata
和 userdata
之间的区别
lightuserdata
是一种特殊的 Lua 类型(以及 nil
、boolean
、number
、string
、table
, thread
等) 包含 C 指针。而已。您不能将 metatable 分配给 lightuserdata
。相反,您可以将 metatable 分配给 userdata
类型。例如,请参阅 Lua File operations,其中文件句柄是 userdata
和方法。 f:read("*all")
f is userdata
该命令等同于f.read(f, "*all")
用整数或 C 指针索引 LUA_REGISTRYINDEX
注册表中广泛使用的方法有两种table。
使用
luaL_ref
创建对 Lua 值的新引用,并将 return 整数值存储在代码中的某处。 IE。要访问 Lua 值,您需要读取包含引用和索引注册表 table 和lua_rawgeti(L, LUA_REGISTRYINDEX, i)
的 C 变量,该整数值在哪里。lua_rawseti(L, LUA_REGISTRYINDEX, i)
也是可以的,但是不要尝试用这种方法重写成nil值!您创建了一个静态 C 变量
static int myvar;
,然后使用lua_rawgetp(L, LUA_REGISTRYINDEX, &myvar)
和lua_rawsetp(L, LUA_REGISTRYINDEX, &myvar)
直接操作存储的 Lua 值。
遗憾的是,我无法比较这两种方法的性能。我觉得他们差不多。