lua标准库加载过程分析

来源:互联网 发布:迷奇化妆品怎么样知乎 编辑:程序博客网 时间:2024/06/05 06:57

我们可以使用函数luaL_openlibs打开lua标准库,这个函数的实现源码如下:

static const luaL_Reg loadedlibs[] = {  {"_G", luaopen_base},  {LUA_LOADLIBNAME, luaopen_package},  {LUA_COLIBNAME, luaopen_coroutine},  {LUA_TABLIBNAME, luaopen_table},  {LUA_IOLIBNAME, luaopen_io},  {LUA_OSLIBNAME, luaopen_os},  {LUA_STRLIBNAME, luaopen_string},  {LUA_MATHLIBNAME, luaopen_math},  {LUA_UTF8LIBNAME, luaopen_utf8},  {LUA_DBLIBNAME, luaopen_debug},#if defined(LUA_COMPAT_BITLIB)  {LUA_BITLIBNAME, luaopen_bit32},#endif  {NULL, NULL}};LUALIB_API void luaL_openlibs (lua_State *L) {  const luaL_Reg *lib;  /* "require" functions from 'loadedlibs' and set results to global table */  for (lib = loadedlibs; lib->func; lib++) {    luaL_requiref(L, lib->name, lib->func, 1);    lua_pop(L, 1);  /* remove lib */  }}
静态数组loadedlibs中的每一个元素既是一个标准库,遍历这个数组,对数组中每一个元素调用luaL_requiref从而加载标准库
LUALIB_API void luaL_requiref (lua_State *L, const char *modname,                               lua_CFunction openf, int glb) {  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");  lua_getfield(L, -1, modname);  /* _LOADED[modname] */  if (!lua_toboolean(L, -1)) {  /* package not already loaded? */    lua_pop(L, 1);  /* remove field */    lua_pushcfunction(L, openf);    lua_pushstring(L, modname);  /* argument to open function */    lua_call(L, 1, 1);  /* call 'openf' to open module */    lua_pushvalue(L, -1);  /* make copy of module (call result) */    lua_setfield(L, -3, modname);  /* _LOADED[modname] = module */  }  lua_remove(L, -2);  /* remove _LOADED table */  if (glb) {    lua_pushvalue(L, -1);  /* copy of module */    lua_setglobal(L, modname);  /* _G[modname] = module */  }}

为了防止重复加载,首先检查当前库是不是已经加载过了,表”_LOADED”中存放的是已经加载过的库或文件,在这个表中检查这个库释放已经加载过了,如果未加载,则把函数和库明压栈,然后调用这个函数,函数执行完后设置_LOADED[modname] = module,缓存返回值,并且表示该库已经加载过了。最后把模块导出到全局变量中:lua_setglobal(L, modname); /* _G[modname] = module */

0 0
原创粉丝点击