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扩展的细节了^_^。

转自:http://blog.chinaunix.net/uid-552961-id-2736410.html

Lua中的require的更多相关文章

  1. 【转载】lua中的require机制

    [转载自]http://blog.chinaunix.net/uid-552961-id-2736410.html lua中的require机制 为了方便代码管理,通常会把lua代码分成不同的模块,然 ...

  2. Lua中的require(转)

    lua中的require机制    为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来.现在看看lua的require的处理流程.1.require机制相关 ...

  3. lua中的require机制

    lua中的require机制 为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来.现在看看lua的require的处理流程.1.require机制相关的数据 ...

  4. lua中的坑

    在工作中使用lua也有一年了,代码也写了不少,踩过不少坑,这里记录一下. table.sort table.sort是lua自带的排序函数,数据量小时,也还是不错的.不过要注意你传入的compare函 ...

  5. Lua中的loadfile,dofile,require使用,最后还有调试

    1.loadfile---只编译,不运行. loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码:另外loadfile不会抛出错误信息而是返回错误代号. loadstr ...

  6. lua中的协程

    lua中的协程和线程类似: 1. 协程拥有自己的独立的栈,局部变量,和指令: 2. 所有协程都可以共享全局变量: 3. 协程不能像线程那样并行执行,协程之间需要相互协调执行,同一个时刻只能运行一个协程 ...

  7. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  8. 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态

    一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...

  9. Lua中的模块与包

    [前言] 从Lua5.1版本开始,就对模块和包添加了新的支持,可是使用require和module来定义和使用模块和包.require用于使用模块,module用于创建模块.简单的说,一个模块就是一个 ...

随机推荐

  1. JAVA学习绘图颜色及其笔画属性设置字体显示文字

    package com.graphics; import java.awt.*; import java.awt.geom.Rectangle2D; import java.util.Date; im ...

  2. 360[警告]跨站脚本攻击漏洞/java web利用Filter防止XSS/Spring MVC防止XSS攻击

    就以这张图片作为开篇和问题引入吧 <options>问题解决办法请参考上一篇 如何获取360站长邀请码,360网站安全站长邀请码 首先360能够提供一个这样平台去检测还是不错的.但是当体检 ...

  3. Mars的自语重出江湖,祝大家端午节安康

    上一篇博客似乎已是非常久远的回忆了,不再码字也已经很多年.<三国演义>里,刘备投靠曹操的那段时间里,2个兄弟问刘备未来,刘备说: 屈身守分,以待天时,不可与命争也. 这样一个时代,每个老百 ...

  4. 了解 JavaScript (6)– 广告条(Banner)

    在 Web 上冲浪时,常常会见到定期在图像之间切换的广告条.我们可以用 JavaScript 来实现,重复循环显示它们. 创建循环的广告条 RotatingBanner.html 页面中在循环的广告条 ...

  5. C++程序中调用MPI并行的批处理命令

    问题来源:在使用MPI时,将程序并行实现了,运行时需要在dos窗口下输入批处理命令,以完成程序的执行. 如:mpiexec -localroot -n 6 d:/mpi/pro.exe 但每次这样挺麻 ...

  6. 设置360调用样式 IE调用样式

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  7. 如何在使用MAMP环境下安装MySQLdb

    我的电脑上没有安装XAMPP,而是安装了MAMP PRO,其实两者都差不多,都是PHP+MySQL+Apache的集成环境,只是MAMP的GUI界面更华丽一些,但是也更复杂一些. 好了不说这些,说说问 ...

  8. iis7下iis安全狗不能用怎么办(安装iis6兼容性)

    is7下iis安全狗不能用怎么办 | 浏览:126 | 更新:2015-05-14 17:11 1 2 3 4 5 6 分步阅读 windows系统iis安全狗是常用的一款软件,针对网站使用很方便.在 ...

  9. Window Server IIS6.0部署webservice请求调用提示请求失败

    在一台window server 2003机器上部署了一个webservice,iis为6.0,奇怪的是.在服务器本机调用webservice成功了,可是在其它client调用却反馈失败.详细什么原因 ...

  10. VC++ 学习笔记(序):神一样的语言

    总的来说,我觉得VC++是一门神一样的语言——它是公认最强大.最复杂的:它一切以效率为第一要务,却又不肯落伍,拼命兼容现在的新的语言设计特点.本来在别的语言很容与就避开的问题,在这里要用很高的技巧去设 ...