您的位置:首页 > 编程语言 > Lua

lua5.1模块注册

2015-09-13 16:04 1381 查看
luaL_openlib是5.1版本下用来模块注册的函数(宏),代码如下:

LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
const luaL_Reg *l, int nup) {
luaL_checkversion(L);
if (libname) {
luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
}
if (l)
luaL_setfuncs(L, l, nup);
else
lua_pop(L, nup);  /* remove upvalues */
}


luaL_openlib函数先获取(不存在则创建)库对应的表,并放置于upvalue下,再在库表中插入以列表参数l中的函数名作为key,函数指针创建的闭包为value的键值对。

看下获取/创建库表的函数luaL_pushmodule的代码:

LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
int sizehint) {
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);  /* get _LOADED table */
lua_getfield(L, -1, modname);  /* get _LOADED[modname] */
if (!lua_istable(L, -1)) {  /* not found? */
lua_pop(L, 1);  /* remove previous result */
/* try global variable (and create one if it does not exist) */
lua_pushglobaltable(L);
if (luaL_findtable(L, 0, modname, sizehint) != NULL)
luaL_error(L, "name conflict for module " LUA_QS, modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname);  /* _LOADED[modname] = new table */
}
lua_remove(L, -2);  /* remove _LOADED table */
}


luaL_pushmodule函数从全局的注册表中找到loaded表,此表中存放了所有加载了的模块。然后从loaded表中查找模块是否已经加载,如果没有加载,则创建全局域表,并加载到loaded表中。luaL_findtable代码如下:

static const char *luaL_findtable (lua_State *L, int idx,
const char *fname, int szhint) {
const char *e;
if (idx) lua_pushvalue(L, idx);
do {
e = strchr(fname, '.');
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {  /* no such field? */
lua_pop(L, 1);  /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, e - fname);
lua_pushvalue(L, -2);
lua_settable(L, -4);  /* set new table into field */
}
else if (!lua_istable(L, -1)) {  /* field has a non-table value? */
lua_pop(L, 2);  /* remove table and value */
return fname;  /* return problematic part of the name */
}
lua_remove(L, -2);  /* remove previous table */
fname = e + 1;
} while (*e == '.');
return NULL;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lua