lua5.1模块注册
2015-09-13 16:04
1381 查看
luaL_openlib是5.1版本下用来模块注册的函数(宏),代码如下:
luaL_openlib函数先获取(不存在则创建)库对应的表,并放置于upvalue下,再在库表中插入以列表参数l中的函数名作为key,函数指针创建的闭包为value的键值对。
看下获取/创建库表的函数luaL_pushmodule的代码:
luaL_pushmodule函数从全局的注册表中找到loaded表,此表中存放了所有加载了的模块。然后从loaded表中查找模块是否已经加载,如果没有加载,则创建全局域表,并加载到loaded表中。luaL_findtable代码如下:
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中的表的概念及其相关操作方法
- Lua编程示例(二):面向对象、metatable对表进行扩展
- 把Lua编译进nginx步骤方法
- Lua脚本自动生成APK包
- Lua中的元表(metatable)、元方法(metamethod)详解
- Lua中的metatable介绍
- Lua中ipair和pair的区别
- Lua中的函数精讲笔记
- 浅谈Lua的面向对象特性
- 详解Lua中的变量相关知识点
- Lua脚本语言入门笔记
- Lua脚本调用外部脚本
- 详解Lua中的if语句的使用方法
- Lua中调用函数使用点号和冒号的区别
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中强大的元方法__index详解
- Lua中调用C++函数示例
- Lua面向对象之类和继承浅析
- Lua性能优化技巧(一):前言
- Lua中获取table长度问题探讨