如何在 Lua 注册表中选择一个合适的 Key
Lua 提供了一个注册表(REGISTRY)让我们的 C 扩展可以安全的把一些运行时数据放进去,而不被 lua 代码碰到。为了让各个 C 扩展库之间可以相安无事的工作,并且对注册表的操作又有较高效率。Lua 大神 Roberto 在神作 Pil 里给出了一个简洁的方案:用 static 变量的地址作为 key 。
静态变量在当前进程中一定拥有惟一的地址,且 lightuserdata 作 key 非常高效。这无疑是一个好方法。
但是,当模块的源码规模变大了以后,我们将代码分散到不同的源文件中。或者几个子模块需要相互协作时。这个方法就有了一定的缺陷。那就是,必须将这个静态变量暴露出来供大家蹂躏;或是写一个内部函数来取得它(其实没有本质区别)。
如果你也碰到这类问题,不妨看看下面的解决方案。
我们可以在子模块间约定一个字符串,比如 "foobar" 。如果能保证字符串惟一,直接用这个字符串做 key 当然也可以。不过效率稍微低了一点。(字符串压栈要多做一次 hash)。但是 lua 的虚拟机可以保证,只要字符串还有人引用,那么字符串对象就永远只有一份放在内存中,且不会被移动。
所以,只要保证这个字符串从未被回收,lua_tostring
的结果就永远是一致的。
明白了吗?每个子模块只要在初始化的时候,顺着调用:
lua_pushstring(L,"foobar");
key=lua_tostring(L,-1);
就可以保证得到的 key 是惟一地址了。
当然,你依然得谨慎选择字符串防止冲突。并且要自己在一个绝对安全的地方对这个字符串做至少一次引用。
Comments
Posted by: undeath | (5) June 26, 2007 09:44 AM
Posted by: Atry | (4) June 18, 2007 08:07 PM
Posted by: jason | (3) June 18, 2007 03:20 PM
Posted by: Tangf | (2) June 18, 2007 02:07 PM
Posted by: Anonymous | (1) June 17, 2007 11:52 PM