Lua 二進制模組 |
|
版本公告:此頁面適用於使用 loadmodule
擴充套件的較早期 Lua 版本(4.0 與 5.0beta)。Lua 5.1 使用 package.loadlib
與 require
。Lua 5.0 使用 loadlib
。)
注意:LuaCheia 是可攜式的 Lua 5.0 維護散佈套件,其中包含並仰賴於此處發起的 loadmodule 協助。
此頁面包含一個 Lua 4.0.1 修補程式,其中新增了一個 loadmodule
函式到預設的 Lua 直譯器中。此頁面也列出了一些可以使用 loadmodule
載入的二進制模組。這些二進制模組可以使用原生程式碼擴充預設 Lua 直譯器的功能,而無需重新編譯任何東西。這使得最終使用者更容易存取有用的函式庫,尤其是一些組合函式庫,這些函式庫會需要重新編譯原始碼才能適用於目標平台。
若要使用此頁面上所列的二進制模組,需要經過修改的直譯器。原始碼和二進制檔案都連結在下方。這段程式碼主要由 IgnacioCastano 所撰寫。它是由 ThatcherUlrich 稍作修改。
套用修補程式的步驟:將正確的 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 的建議事項和範例
模型作者:請在下方加入模型,並附上簡短說明。請包含 wiki 或網頁連結,讓使用者能取得模型的完整說明,並下載模型二進位檔(以及原始程式碼,若有)。
以下列出可與上述詮譯器搭配使用的二進位檔模型。(其中許多模型也能透過較傳統的方式整合至 Lua,方法是在自訂的詮譯器上編譯來源程式,並透過靜態連結的方式建立連結。)
「我更新原始程式碼修補程式:增列一些 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