27.3.1 The Registry

registry 一直位于一个由LUA_REGISTRYINDEX定义的值所对应的假索引(pseudo-index)的位置。一个假索引除了他对应的值不在栈中之外,其他都类似于栈中的索引。Lua API中大部分接受索引作为参数的函数,也都可以接受假索引作为参数—除了那些操作栈本身的函数,比如lua_removelua_insert。例如,为了获取以键值 "Key" 保存在registry中的值,使用下面的代码:

lua_pushstring(L, "Key");

lua_gettable(L, LUA_REGISTRYINDEX);

registry就是普通的Lua表,因此,你可以使用任何非nilLua值来访问她的元素。然而,由于所有的C库共享相同的registry ,你必须注意使用什么样的值作为key,否则会导致命名冲突。一个防止命名冲突的方法是使用static变量的地址作为keyC链接器保证在所有的库中这个key是唯一的。函数lua_pushlightuserdata将一个代表C指针的值放到栈内,下面的代码展示了使用上面这个方法,如何从registry中获取变量和向registry 存储变量:

/* variable with an unique address */

static const char Key = 'k';

 

/* store a number */

lua_pushlightuserdata(L, (void *)&Key);  /* push address */

lua_pushnumber(L, myNumber);  /* push value */

/* registry[&Key] = myNumber */

lua_settable(L, LUA_REGISTRYINDEX);

 

/* retrieve a number */

lua_pushlightuserdata(L, (void *)&Key);   /* push address */

lua_gettable(L, LUA_REGISTRYINDEX);  /* retrieve value */

myNumber = lua_tonumber(L, -1);  /* convert to number */

我们会在28.5节中更详细的讨论light userdata

当然,你也可以使用字符串作为registrykey,只要你保证这些字符串唯一。当你打算允许其他的独立库房问你的数据的时候,字符串型的key是非常有用的,因为他们需要知道key的名字。对这种情况,没有什么方法可以绝对防止名称冲突,但有一些好的习惯可以采用,比如使用库的名称作为字符串的前缀等类似的方法。类似lua或者lualib的前缀不是一个好的选择。另一个可选的方法是使用universal unique identifieruuid),很多系统都有专门的程序来产生这种标示符(比如linux下的uuidgen)。一个uuid是一个由本机IP地址、时间戳、和一个随机内容组合起来的128位的数字(以16进制的方式书写,用来形成一个字符串),因此它与其他的uuid不同是可以保证的。


相关链接:
lua程序设计目录 - 中国lua开发者 - lua论坛