加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua中的require机制

发布时间:2020-12-14 22:26:15 所属栏目:大数据 来源:网络整理
导读:http://blog.chinaunix.net/u/2326/showart_726571.html ? lua中的require机制 ?? ?为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来。 现在看看lua的require的处理流程。 1、require机制相关的数据和函数 ?? ?packag
http://blog.chinaunix.net/u/2326/showart_726571.html
?
lua中的require机制 ?? ?为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来。 现在看看lua的require的处理流程。 1、require机制相关的数据和函数 ?? ?package.path:保存加载外部模块(lua中"模块"和"文件"这两个概念的分界比较含糊,因为这个值在不同的时刻会扮演不同的角色)的搜索路径,这种路径是"模板式的路径",它里面会包含可替代符号"?",这个符号会被替换,然后lua查找这个文件是否存在,如果存在就会调用其中特定的接口。典型的值为: ?? ?"./?.lua;./?.lc;/usr/local/?/init.lua" ?? ?如果lua代码中调用:require("hello.world") ?? ?那么lua会依次查找: ?? ?./hello/world.lua ==>这里"hello.world"变成了"hello/world",并替换了模型"./?.lua" ?? ?./hello/world.lc ?? ?..... ?? ?(这种处理方式和python类似,只不过不需要__init__.py,也有调用python中的__init__.py) ?? ?package.path在虚拟机启动的时候设置,如果存在环境变量LUA_PATH,那么就用该环境变量作为 ?? ?它的值,并把这个环境变量中的";;"替换为luaconf.h中定义的默认值,如果不存在该变量就直接使用 ?? ?luaconf.h定义的默认值 ?? ? ?? ?package.cpath:作用和packag.path一样,但它是用于加载第三方c库的。它的初始值可以通过环境变量 ?? ?LUA_CPATH来设置 ?? ? ?? ?package.loadlib(libname,func):相当与手工打开c库libname,并导出函数func返回,loadlib其实是ll_loadlib ?? ? 2.require的处理流程: ?? require(modelname) ?? require(在lua中它是ll_require函数)的查找顺序如下: ? ??? ?a.首先在package.loaded查找modelname,如果该模块已经存在,就直接返回它的值 ? ??? ?b.在package.preload查找modelname,如果preload存在,那么就把它作为loader,调用loader(L) ? ??? ?c.根据package.path的模式查找lua库modelname,这个库是通过module函数定义的,对于顶层的lua库,文件名和库名是一样的而且不需要调用显式地在lua文件中调用module函数(在ll_require函数中可以看到处理方式),也就是说lua会根据lua文件直接完成一个loader的初始化过程。 ? ??? ?d.根据package.cpath查找c库,这个库是符合lua的一些规范的(export具有一定特征的函数接口),lua先已动态的方式加载该c库,然后在库中查找并调用相应名字的接口,例如:luaopen_hello_world ? ??? ?e.已第一个"."为分割,将模块名划分为:(main,sub)的形式,根据package.cpath查找main,如果存在,就加载该库并查询相应的接口:luaopen_main_sub,例如:先查找 hello库,并查询luaopen_hello_world接口 ? ??? ?f.得到loder后,用modname作为唯一的参数调用该loader函数。当然参数是通过lua的栈传递的,所以loader的原型必须符合lua的规范:int LUA_FUNC(lua_State *L) ? ??? ? ? ? ??? ?ll_require会将这个loader的返回值符给package.loaded[modelname],如果loader不返回值同时 package.loaded[modelname]不存在时,ll_require就会把package.loaded[modelname]设为true。最后ll_reuqire把package.loaded [modelname]返回给调用者。 ?? ? 3.module的处理流程 ??? module(name,cb1,cb2,...) ?? ? ??? a.如果package.loaded[name]是一个table,那么就把这个table作为一个mod ??? b.如果全局变量name是一个table,就把这个全局变量作为一个mod ??? c.创建table:t = {[name]=package.loaded[name],["_NAME"]=name,["_M"]=t,["_PACKAGE"]=*name*(删除了最后的".XXXX"部分)}. 如果name是一个以点分割的串,那么得到的mod类似这个样子: ????? hello.world==> {["hello"]={["world"]={XXXXXXX}}} ??? d.依次调用cbs: ????? cb1(mod),cb2(mod),... ???? ? ??? e.将当前模块的环境设置为mod,同时把package.loaded[name] = mod?? ? ?? ? ? 清楚了lua关于模块的处理,就比较容易理解写lua扩展的细节了^_^。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读