简体   繁体   English

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

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

So with the Lua C API you can save a Lua value in the registry and retrieve it later.因此,使用 Lua C API,您可以在注册表中保存 Lua 值并在以后检索它。 There are different ways to do it, you can create a variable and use it's pointer as the key in the registry as it's always unique.有不同的方法可以做到这一点,您可以创建一个变量并将它的指针用作注册表中的键,因为它始终是唯一的。 You would push the pointer as light userdata.您可以将指针作为轻用户数据推送。

You can also create a reference using LuaL_ref(L, LUA_REGISTRYINDEX) .您还可以使用LuaL_ref(L, LUA_REGISTRYINDEX)创建引用。 What is the advantage of one over the other?一个比另一个有什么优势? When to use references and when to use pointers?何时使用引用,何时使用指针?

Also with references, as it is called a reference, if the Lua garbage collector collects the Lua value, will the value in the registry be nil ?还有引用,因为它被称为引用,如果 Lua 垃圾收集器收集 Lua 值,注册表中的值会是nil吗? What if Lua updates the Lua value, will the value in the registry also change?如果 Lua 更新了 Lua 值,注册表中的值是否也会改变?

Lua registry is just another lua table, easily accessible via predefined "special" index. Lua 注册表只是另一个 lua 表,可以通过预定义的“特殊”索引轻松访问。 I guess you don't need explanations on how Lua table is different from light userdata.我想你不需要解释 Lua 表与轻用户数据的不同之处。
It doesn't really matter how you will index registry table, as long as you can store that key on C/C++ side.您将如何索引注册表并不重要,只要您可以将该键存储在 C/C++ 端即可。 For your convenience there's already functions (luaL_ref/luaL_unref) giving you integer key that is easy to store and move around.为了您的方便,已经有函数 (luaL_ref/luaL_unref) 为您提供易于存储和移动的整数键。

About garbage collection - rules are always the same.关于垃圾收集 - 规则始终相同。 As long as value is stored in table that wasn't marked as weak table (registry is not weak table), that value won't be cleared.只要值存储在未标记为弱表(注册表不是弱表)的表中,该值就不会被清除。 You must explicitly remove value from the registry.您必须从注册表中明确删除值。

Changing value will obey normal Lua rules.更改值将遵循正常的 Lua 规则。 Assigning new immutable value to some variable won't change value stored in registry, ie registry won't follow updates to some variable.将新的不可变值分配给某个变量不会改变存储在注册表中的值,即注册表不会跟踪某个变量的更新。 But changing content of mutable value (table etc) is ok, since registry and variable will refer same value.但是更改可变值(表等)的内容是可以的,因为注册表和变量将引用相同的值。

In addition to previous answer:除了之前的答案:

Differences between Lua lightuserdata and userdata Lua lightuserdatauserdata区别

lightuserdata is a special Lua type (as well as nil , boolean , number , string , table , thread etc.) containing C pointer. lightuserdata是包含 C 指针的特殊 Lua 类型(以及nilbooleannumberstringtablethread等)。 Nothing more.没有更多了。 You can't assign metatable to lightuserdata .您不能将元表分配给lightuserdata On the contrary, you can assign metatable to userdata type.相反,你可以分配到元表userdata类型。 For example see Lua File operations , where file handle is userdata with methods.例如看到Lua的文件操作,其中的文件句柄是userdata与方法。 f:read("*all") f is userdata the command is equivalent to f.read(f, "*all") f:read("*all") f 是userdata命令等价于f.read(f, "*all")

Indexing LUA_REGISTRYINDEX with integer or C pointer使用整数或 C 指针索引LUA_REGISTRYINDEX

There are two methods that are widely used on registry table.注册表中有两种广泛使用的方法。

  1. Create new reference to Lua value with luaL_ref and store the return integer value somewhere in your code.使用luaL_ref创建对 Lua 值的新引用,并将返回的整数值存储在代码中的某处。 Ie to access the Lua value you'll need to read C variable holding the reference and index registry table with lua_rawgeti(L, LUA_REGISTRYINDEX, i) where is that integer value.即要访问 Lua 值,您需要使用lua_rawgeti(L, LUA_REGISTRYINDEX, i)读取包含引用和索引注册表的 C 变量lua_rawgeti(L, LUA_REGISTRYINDEX, i)其中该整数值在哪里。 lua_rawseti(L, LUA_REGISTRYINDEX, i) is also possible, but don't try rewrite to a nil value with this method! lua_rawseti(L, LUA_REGISTRYINDEX, i)也是可能的,但不要尝试用这种方法重写为 nil 值!

  2. You creating a static C variable static int myvar;您创建了一个静态 C 变量static int myvar; and then use lua_rawgetp(L, LUA_REGISTRYINDEX, &myvar) and lua_rawsetp(L, LUA_REGISTRYINDEX, &myvar) for manipulation of stored Lua value straight-forward.然后使用lua_rawgetp(L, LUA_REGISTRYINDEX, &myvar)lua_rawsetp(L, LUA_REGISTRYINDEX, &myvar)直接操作存储的 Lua 值。

Unfortunately I can't compare the performance of both methods.不幸的是,我无法比较这两种方法的性能。 I think they are almost the same.我认为它们几乎相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM