Lua 二進制模組

lua-users home
wiki

此處的慣例、文件和程式碼是 ThatcherUlrich 提議的 Lua「社群標準」二進制模組系統。請視它為現正研擬中的「alpha」版本。請將意見和批評寄給 Lua 郵件清單。

版本公告:此頁面適用於使用 loadmodule 擴充套件的較早期 Lua 版本(4.0 與 5.0beta)。Lua 5.1 使用 package.loadlibrequire。Lua 5.0 使用 loadlib。)

注意:LuaCheia 是可攜式的 Lua 5.0 維護散佈套件,其中包含並仰賴於此處發起的 loadmodule 協助。

此頁面包含一個 Lua 4.0.1 修補程式,其中新增了一個 loadmodule 函式到預設的 Lua 直譯器中。此頁面也列出了一些可以使用 loadmodule 載入的二進制模組。這些二進制模組可以使用原生程式碼擴充預設 Lua 直譯器的功能,而無需重新編譯任何東西。這使得最終使用者更容易存取有用的函式庫,尤其是一些組合函式庫,這些函式庫會需要重新編譯原始碼才能適用於目標平台。


帶有 loadmodule 的 Lua 4.0.1

若要使用此頁面上所列的二進制模組,需要經過修改的直譯器。原始碼和二進制檔案都連結在下方。這段程式碼主要由 IgnacioCastano 所撰寫。它是由 ThatcherUlrich 稍作修改。

原始碼

[lua-4.0.1-loadmodule.patch]

套用修補程式的步驟:將正確的 Lua 散佈套件解壓縮到新的目錄中。執行 cd 指令切換到該目錄的最上層,然後執行修補程式。例如,如果你已將 lua.tar.gz 和上述修補程式檔案儲存在 ~/src 中

        cd ~/src
        tar -xzvf lua.tar.gz
        mv lua-4.0.1 lua-4.0.1-loadmodule
        cd lua-4.0.1-loadmodule
        patch -p1 < ../lua-4.0-loadmodule-2002-11-21.patch

在建置之前請務必瀏覽 config 檔案,以確認已針對你的平台設定選項。

二進制檔案

以下的二進制檔案使用標準 Lua 4.0.1 散佈套件編譯,並加上上述修補程式。下載並直接使用即可。

[GNU/Linux-i386] | [Win32] | Mac | *BSD | Solaris

使用者說明

在你的 Lua 腳本中,執行

loadmodule("模組名稱")

這樣會從模組中載入程式碼,並初始化與 Lua 的繫結。請查看個別模組的文件,以瞭解如何從 Lua 使用該模組。

loadmodule 函式會傳回兩個值。一個判斷 loadmodule 是否成功的布林值,以及一個字串用於描述函式庫(如果成功)或描述錯誤(如果失敗)。

ok, str = loadmodule "modulename"

if not ok then
	error( str )
else
	print( "using " .. str )
end

或者在大部分情況下你會執行

assert( loadmodule "模組名稱" )

而如果模組名稱不存在,它會印出

錯誤:斷言失敗!無法載入模組 '模組名稱'

函式庫命名慣例

Lua 函式庫假設以「lua」為前綴,以區分包裝函式庫和被包裝的對應函式庫。因此,在執行以下動作時

loadmodule("SDL")

您是載入 luaSDL 函式庫。此外,每個平台都有其自己的命名方式。目前 loadmodule 在 Win32 和支援 DLFCN(Linux、OSX 和大多數 UNIX 風格)的系統中受支援。

例如,在 Win32 函式庫中,其副檔名為「.dll」,因此 luaSDL 的函式庫名稱為

luaSDL.dll

而在 Linux 系統中,則為

libluaSDL.so

不過,在 Lua 腳本中,您不必在意系統慣例,您只需要執行 loadmodule("SDL")

函式庫搜尋路徑

函式庫搜尋路徑視系統而定。

Linux 會依下列順序搜尋函式庫

SunOS? 會依下列順序搜尋函式庫

Windows 會依下列順序搜尋函式庫

此外,luamodule 會在預先定義的搜尋路徑中尋找模組。該路徑由 LUA_LIBPATH 全域金鑰設定。如果鍵不存在,則會在 LUA_LIBPATH 環境變數中尋找自訂路徑。這應讓您使用系統中已安裝的較新版本函式庫。

模組作者說明

要匯出的函式

Lua 二進位模組是一個特定於平台的共用函式庫(例如,大多數 Unix 系統中的 .so 或 Win32 中的 .DLL),可匯出這兩個特殊函式

    const char* luaLM_version(void);
    int luaLM_import(lua_State* L);

函式 luaLM_version() 應傳回您的模組編譯對應的 LUA_VERSION 值;例如,在您的原始程式碼中通常應如下所示

	const char* luaLM_version(void)
	{
		return LUA_VERSION;
	}

loadmodule 會先呼叫此函式,以確保二進位模組與它要載入的 Lua 詮譯器相容。

函式 luaLM_import(lua_State* L) 是由 loadmodule 呼叫,用於實作您的繫結。您在此處使用一般的 Lua API,將模組的函式和變數繫結到指定的 lua_State

命名空間

強烈建議將所有綁定項目放入命名空間中。亦即,所有欲綁定至 Lua 的函數和值都應包含在一個資料表中。有關 Lua 命名空間的說明,請參閱 LTN7 [1]。建議此資料表的命名對應於模型名稱。舉例來說,由 loadmodule("SDL") 載入的 luaSDL 模型會將所有綁定項目放入名為「SDL」的資料表中。若需要,使用者可依便利性為此資料表指派不同的名稱。

註解:loadmodule 并未強制使用命名空間。但若能遵守此準則,使用者會更滿意。

待辦事項:說明模型中的靜態狀態為何危險

待辦事項:提供使用 tolua 的建議事項和範例

簡單的教學課程

請參閱 BinaryModuleTutorial。說明如何將任何既有的 Lua 延伸模組轉為可由 loadmocule 使用的動態連結函式庫。

模型作者:請在下方加入模型,並附上簡短說明。請包含 wiki 或網頁連結,讓使用者能取得模型的完整說明,並下載模型二進位檔(以及原始程式碼,若有)。


二進位檔模型

以下列出可與上述詮譯器搭配使用的二進位檔模型。(其中許多模型也能透過較傳統的方式整合至 Lua,方法是在自訂的詮譯器上編譯來源程式,並透過靜態連結的方式建立連結。)


「能否讓模組回傳自身的版本資訊?例如現在的 loadmodule("fuzzy") 會印出「使用 fuzzy」,版本相依的用法改用「fuzzy-x.yy.zz」可能比較好?或…可以回傳「資訊」表格,它的欄位包含開發人員、版本、授權條款、說明等…」,Hakki Dogusan 發表。

「我更新原始程式碼修補程式:增列一些 Makefile 變更,以提供更好的 Linux .so 支援。.so 和可執行檔現在都附加了 $(V)(因此,直譯器為 lua-4.0,主程式庫為 liblua-4.0.so)。此外,還有新的二進制檔和包含可執行檔與 .so 的 tarball」,ThatcherUlrich 發表。

「修補程式中有一些錯誤,如果你更變靜態程式庫名稱,也必須變更 src/Makefile 和 src/lib/Makefile 中的目標。你還移除了 .def 檔。你其實可以透過在 Makefile 中註解一行並重新定義 LUA_API 和 LUALIB_API 來產生 .def 檔,但我認為直接使用既有的 .def 檔,不變動任何內容比較容易。如果有人也遇到新的修補程式問題,這裡還有舊的修補程式:[修補程式]」,IgnacioCastano 發表。

「我已上傳一個 [zip 檔],其中包含我的 lua-loadmodule 目前樹狀結構的所有原始程式碼和專案檔。」,MartinSpernau 發表。

「我已變更 loadmodule,讓它在檢查版本時忽略版本號。這是新的 [修補程式]。如果沒有人回報任何錯誤,我會在幾天後更新以上的連結。」,IgnacioCastano 發表。

「這裡針對 lua-5.0-beta 有新的修補程式:[修補程式]。它的測試並不完整,因此請謹慎使用。」,IgnacioCastano 發表。

「lua-5 的 loadmodule 新增功能非常棒;我正在使用它製作一個 lua-5 LuaSqlite 可載入的二進制模組。然而,如果其語意和 [載入 (TN11)] 相同,會不會更好?這將讓模組較不依賴於全域名稱空間。

「坦白說,我想 LTN11 增加了複雜度來解決實際上並非問題的問題。事實是,模組需要唯一的名稱,所以我認為直接解決名稱衝突比較不會混淆,且堅持 LTN7 的慣例。」,ThatcherUlrich 發表。

基於我的觀點,LTN11 具有低複雜性(如果有的話)且能解決許多問題 - 儘管這些問題並非所有人都會遇到。舉例來說,它允許同一個介面的兩個實作(如果你喜歡的話,也可說是同一個模組的兩個版本)同時使用,這對測試來說非常地實用。它也能讓沙箱模組更實用,且開啟了一個可能性,也就是擁有內部狀態(例如 readline,或 Lua 本身)的模組可以有多個實例。從 C 的角度來看,「額外的複雜度」僅僅是模組開啟函式使用一個作為參數傳遞的表格,而不是將它直接新增到全域性的命名空間;而這個表格本身則由套件系統提供。 -RiciLake


最新變更 · 喜好設定
編輯 · 歷史紀錄
上次編輯時間為 2009 年 12 月 24 日 下午 5:11 GMT (比較)