lua中的require機制

2021-07-10 01:39:35 字數 2247 閱讀 9882

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是乙個以點分割的串,那麼得到的mod類似這個樣子:

hello.world==> }}

d.依次呼叫cbs:

cb1(mod), cb2(mod),...

e.將當前模組的環境設定為mod,同時把package.loaded[name] = mod    

清楚了lua關於模組的處理,就比較容易理解寫lua擴充套件的細節了^_^。

lua中的require機制

lua中的require機制 2008 06 05 09 13 27 分類 python ruby lua中的require機制 為了方便 管理,通常會把lua 分成不同的模組,然後在通過require函式把它們載入進來。現在看看lua的require的處理流程。1 require機制相關的資料和函...

lua中的require函式

lua提供高階的require函式來載入執行庫,lua中的require函式功能主要有 1 require函式會搜尋目錄載入檔案 2 require會判斷是否檔案已經載入避免重複載入同一檔案。由於上述特徵,require在lua中是載入庫的更好的函式。require使用的路徑和普通我們看到的路徑還有...

lua中require的庫檔案問題

這幾天給lua的require問題弄的很是糾結。先是看別人 require mod.c 由於同一目錄下還有乙個mod.c檔案,讓我覺得lua很強大,可以解析c的函式並變成自己的api,雖說自己明明已經編譯了用於擴充套件lua的.so。後來發現不對,終於蝸牛同學提醒了我一下,lua會將 mod.c 按...