ulua 路徑小記 以及 lua require 機制整理

ulua 路徑小記

ToLua
在學習ulua時,require模塊的根路徑可以為項目的Lua文件夾或者ToLua文件夾(Editor下),但是在package.pathpackage.cpath中并沒有看到當前項目的路徑,那require是如何找到Lua和ToLua文件夾的路徑的呢?

  • ulua在初始化LuaState時,會先解析package.path, 并將其存入LuaFileUtilsSearchPaths中(LuaState.cs line:603),并將Lua和ToLua的目錄添加其中(LuaState.cs line:187)。
  • 在LuaState的構造函數中,會調用ToLua.OpenLib(T),該方法定義了一下特殊方法,可以在lua中使用,如typeof等。
  • OpenLib方法會在package.loaders數組中,再添加一個loader,并且將其放到數組的第二個位置。(ToLua.cs line:192)注:Lua require模塊時,會依次調用package.loader中的方法,找到則返回
  • loader的作用就是檢測傳入的文件名(module名),是否在LuaFileUtilsSearchPaths,如果存在就讀取文件,若不存在則返回空(LuaFileUitls.cs line:170)

Lua require 相關整理(基于lua 5.1)

摘自http://cloudwu.github.io/lua53doc/manual.html#6.3
根據lua5.1 手冊做了部分修改

package.preload

為指定的模塊,設置loader,在require模塊時,先去查詢這張表,如果有值,則使用preload中的loader(可以用于修改特殊模塊的加載策略)

package.path

這個路徑被 require 在 Lua 加載器中做搜索時用到。
在啟動時,Lua 用環境變量 LUA_PATH來初始化這個變量。 或采用 luaconf.h 中的默認路徑。 環境變量中出現的所有 ";;" 都會被替換成默認路徑。

package.cpath

這個路徑被 require 在 C 加載器中做搜索時用到。

Lua 用和初始化 Lua 路徑 package.path 相同的方式初始化 C 路徑 package.cpath 。 它會使用環境變量LUA_CPATH初始化。 要么就采用 luaconf.h 中定義的默認路徑。

package.loaders(Lua5.3中, 改名為searchers)

用于 require控制如何加載模塊的表。

這張表內的每一項都是一個 查找器函數。 當查找一個模塊時, require 按次序調用這些查找器, 并傳入模塊名(require的參數)作為唯一的一個參數。 此函數可以返回另一個函數(模塊的 加載器)加上另一個將傳遞給這個加載器的參數。 或是返回一個描述為何沒有找到這個模塊的字符串 (或是返回 nil 什么也不想說)。

Lua 用四個查找器函數初始化這張表。

第一個查找器就是簡單的在 package.preload 表中查找加載器。

第二個查找器用于查找 Lua 庫的加載庫。 它使用儲存在 package.path 中的路徑來做查找工作。路徑是一個包含有一系列以分號分割的 模板 構成的字符串。 對于每個模板,都會用 name 替換其中的每個問號(如果有的話)。 且將其中的 點替換為系統的目錄分割符(如 Unix中的"/")。 然后嘗試打開這個文件名。

例如,如果路徑是字符串

  "./?.lua;./?.lc;/usr/local/?/init.lua"

搜索 foo.a 這個名字將 依次嘗試打開文件 ./foo/a.lua , ./foo/a.lc ,以及 /usr/local/foo/a/init.lua

第三個查找器用于查找 C 庫的加載庫。 它使用儲存在 package.cpath中的路徑來做查找工作。 例如,如果 C 路徑是這樣一個字符串

"./?.so;./?.dll;/usr/local/?/init.so"

查找器查找模塊 foo 會依次嘗試打開文件 ./foo.so./foo.dll, 以及 /usr/local/foo/init.so。 一旦它找到一個 C 庫, 查找器首先使用動態鏈接機制連接該庫。 然后嘗試在該庫中找到可以用作加載器的 C 函數。 這個 C 函數的名字是 "luaopen_" 緊接模塊名的字符串, 其中字符串中所有的下劃線都會被替換成點。 此外,如果模塊名中有橫線, 橫線后面的部分(包括橫線)都被去掉。 例如,如果模塊名為 a.b.c-v2.1, 函數名就是luaopen_a_b_c

第四個搜索器是 一體化加載器。 它從 C 路徑中查找指定模塊的根名字。 例如,當請求 a.b.c 時, 它將查找 a 這個 C 庫。 如果找得到,它會在里面找子模塊的加載函數。 在我們的例子中,就是找 luaopen_a_b_c。 利用這個機制,可以把若干 C 子模塊打包進單個庫。 每個子模塊都可以有原本的加載函數名。

require(modname)

加載一個模塊。 這個函數首先查找 package.loaded表, 檢測 modname 是否被加載過。 如果被加載過,require 返回 package.loaded[modname] 中保存的值。(防止重復加載) 否則,它試著為模塊尋找 加載器

首先 require 查找 package.preload[modname] 。 如果這里有一個值,這個值(必須是一個函數)就是那個加載器。 否則 require 使用 Lua 加載器去查找 package.path 的路徑。 如果查找失敗,接著使用 C 加載器去查找 package.cpath 的路徑。 如果都失敗了,再嘗試 一體化 加載器 (參見 package.loaders

每次找到一個加載器,require 都用一個參數調用加載器: modname 。 如果加載器返回非空值, require 將這個值賦給package.loaded[modname]。 如果加載器沒能返回一個非空值用于賦給 package.loaded[modname]require 會在那里設入 true 。 無論是什么情況,require 都會返回 package.loaded[modname] 的最終值。

如果在加載或運行模塊時有錯誤, 或是無法為模塊找到加載器, require 都會拋出錯誤。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容