Lua 可嵌入並使用其他程式語言編寫的程式碼或應用程式擴充 [1]。其他語言的程式碼及數值可以公開給 Lua,反之亦然。以下列出連結 Lua 與其他語言的低階與高階解決方案。
Lua C API
連結至 Lua 最直接的方法是使用 Lua C API。C API 包含兩個部分:基本 API (lua.h) 提供 C 與 Lua 之間所有互動的基本函式,而 輔助函式庫 (lauxlib.h) 則提供一些常見任務的高階函式。[2]
啟用 API 檢查
預設情況下,Lua C API 幾乎不會檢查傳遞給它的引數的健全性。傳遞不正確的堆疊索引,例如,可能會導致分段錯誤或隨機資料毀損。您應該在任何除錯建置中始終啟用 API 檢查。您可以透過編譯選項 -DLUA_USE_APICHECK
來執行此動作。luaconf.h
使用此 C 巨集定義 luai_apicheck
來在不同位置呼叫 assert()
(您也可以編輯此定義來執行其他可能更有用的操作)。
範例
透過檢查 Lua 自有標準函式庫 (src/*lib.c
) 的原始碼,可以找到一些使用 C API 的範例。舉例而言,數學函式庫 (math.*
) 是在 src/lmathlib.c
檔案中實作。這個檔案的基本型式如下所示。首先,我們匯入各種標頭,包括 C API (lua.h) 和輔助函式庫 (lauxlib.h)
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
然後,會定義各種 C 實作的 Lua 函式。這些函式都擁有相同的簽章,並且會透過 Lua 自有的堆疊傳遞引數。舉例而言,sin 函式的定義如下所示。luaL_check_number()
用來檢查 sin
函式引數的正確類型。lua_pushnumber()
用來傳回計算出的正弦值。請注意,math_sin()
函式的傳回值是傳回值的數量(Lua 函式可以傳回多個值)。
static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
return 1;
}
這些函式透過建立函式指標和名稱的表格,然後呼叫 luaL_register()
來註冊到 Lua。常數 pi
和 huge
會個別設定。此註冊程式碼置於名為 luaopen_math()
的函式中,而這個函式可以直接呼叫(例如從 linit.c),或透過動態方式(使用 Lua 的共用程式庫載入機制,例如透過 require
,來進行呼叫)。
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"cos", math_cos},
{"sin", math_sin},
... etc...rest of table not included, but make sure you finish of with:
{NULL, NULL}
};
/*
** Open math library
*/
LUALIB_API int luaopen_math (lua_State *L) {
luaL_register(L, LUA_MATHLIBNAME, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
return 1;
}
使用 C/C++ 與 Lua 建立繫結
C
- [LuaAutoC] (5.2) - 能夠在執行階段自動封裝 C 函式和結構。
- [LuaNativeObjects] (5.1) - 一個由 Lua 寫成的 C 繫結產生器。將 C 結構轉換為物件。
- [luapi] (5.0) - 為官方 Lua API 所提供的一個 C API。
- [CaLua] (5.0) - 一種能夠將 C 函式和結構繫結到 Lua 的方法,並在 Lua 中使用 C 指標、陣列和函式。(使用 x86 組合語言)
C 外部函式介面 (FFI)
- [Alien] (5.1) - 針對 Lua 的外部函式介面 (FFI)。透過使用 [FFI],Lua 程式可以在不需撰寫 C「膠水」的情況下直接呼叫 C 函式,因此您可以使用 Alien 使用 Lua 撰寫 C 的延伸套件。(封裝 libffi)
- [C/Invoke for Lua] (5.1) - 使用 [C/Invoke] 從 Lua 直接呼叫 C 函式庫(DLL、.so 檔案),如同 Microsoft 的 P/Invoke 和 Python 的 ctypes。(類似於 Alien)
- [The LuaJIT FFI] 讓您可以從 Lua 程式呼叫外部 C 函式,並使用 C 資料結構。它解析一般 C 宣告,並支援 C99,以及一些 GCC/MSVC/C++ 延伸套件。
- [luaffi] (5.1) - 針對 Lua 的 LuaJIT FFI 實作。
- [cffi-lua] (5.1、LuaJIT、5.2、5.3、5.4) - 主要與 LuaJIT FFI 相容(但可以整合新的 Lua 版本),但具可攜性(基於 libffi),並從頭開始實作。
C 內嵌
- [lua-tcc] (5.1) - Fabrice Bellard 所開發,針對 TCC 的簡易介面,是一種快速執行階段 C 編譯器,它允許 Lua 程式碼編譯 C 程式碼,並在執行階段以 Lua 可呼叫 C 函式的形式註冊此程式碼。故意限制其功能,以避免 TCC 在多重環境中產生的錯誤,因為這在 Lua 中實在太誘人了。
- [Luatcc] (5.1) - 另一個更完整的 libtcc Lua 繫結,而 libtcc 是 [Tiny C Compiler] 的核心函式庫。它允許從 Lua 編譯和載入 C 程式碼,包括直接從 C 原始碼載入 C 模組的功能。
- InlineCee 提供類似的作法,呼叫其他過程外的編譯器。
C++
有人開發出各種 C++ 或 C++ 樣板繫結,以簡化 C++ 中的流程
- [Luaaa] (5.1、5.2、5.3、5.4) - 一個將 C++ 類別及函數匯出至 Lua 的單一標頭檔。無依賴性、輕量級。支援匯出 lambda、雙向呼叫回、將 stl 容器對應至 lua 表格、從已匯出類別繼承、可自訂的記憶體配置;使用介面容易;將原生物件匯出成使用者資料而非表格,以獲得更好的效能;有選項可停用 STL/RTTI 以進行嵌入式開發。
- [MiniLua (5.3、5.4)] - 最小的 Lua 介面,用於載入 lua 檔案並將值傳遞進您的 C++ 應用程式中。
- [Lua-Adapter] (5.3、5.4) - 使用此輕量級的包裝器/適配器類別,作為 Lua 與 C++ 之間的簡單「介面」。
- [CppLua] (5.0 & 5.1) - 一個 Lua API 的 C++ 封裝;處理類別成員函數。
- [LuaCppInterface] (5.2) - 一個 Lua API 的 C++ 封裝。使用 TMP (範型元程式) 使得呼叫/傳遞函數、處理非同步程式及填寫表格變得容易且類型安全。
- [sol2] (5.1、Lua JIT、5.2 & 5.3) - 一個快速、強大且容易使用的 C++14 封裝,可用於 API,包括表格索引、使用者自訂類型、元方法、非同步程式等的支援。
- [sol] (5.2) - 一個使用方便且類型安全的 C++11 封裝,可用於 Lua API。
- [Diluculum] (5.1) - 一個旨在使 C++ 與 Lua 並存更協調的函式庫。
- [Tomaka17 的 lua 封裝] (5.2) - 使用支援類別及函數註冊、自訂成員函數、多重回傳值、表格等的 C++11 進行 Lua 簡易繫結。
- [Luabind] (5.1 & [5.2]) - 一個基於範型的 C++ 類別與函數繫結,使用 Boost 函式庫。此函式庫似乎已由 [原作者] 棄用,但有一些比較或多或少積極維護的 [分叉程式] 存在,例如 [3] 或 [4]。
- [LuaBridge] (5.1 & 5.2) - 輕量級、無依賴性、基於範型的函式庫,用於將 C++ 類別/函數匯出至 Lua 環境。
- [LuaBridge3] (5.1、5.2、5.3、5.4、LuaJIT & Luau,有無例外) - 輕量級、無依賴性、基於範型的函式庫,用於將 C++ 類別/函數匯出至 Lua 環境,LuaBridge 的後繼者?具有更多功能和修正。
- [SLB] (5.2) - 簡單的 Lua Binder,一個跨平台、輕量級、易於整合、基於範型的函式庫。與 Luabind 或 boost-python 非常相似,但 SLB 不需要 boost 或任何其他依賴項。
- [Luna] (4.0)、LunaWrapper (5.1) 及 LunaFive (5.2) - 清理、基於樣版的 C++ 類繫結 Lua 的方法。參見 [LTN5] 及 SimplerCppBinding。
- LunaWrap (5.2 & 5.3) - 清理、基於樣版的將任意型別傳送到 Lua 和取得 Lua 任意型別的方式,以及 C++ 成員函式的 COMPILE-TIME「代理」函式(「int foo(lua_State*)」)產生器!
- [MLuaBind] (5.1) - 使用 Loki 函式庫的 C++ 類繫結及函式基於樣版的繫結。
- [MultiScript] (5.1) - 一個簡單函式庫,展示 Lua 獨立的 C++ 介面,以繫結 C++ 類及函數。
- [OOLua] (5.1、5.2 & 5.3) - 沒有依賴項目的跨平台樣版產生器繫結。
- [Selene] (5.1、5.2、5.3) - 非死不可簡單且直覺的 C++11 繫結支援類別註冊和函式。
- [Sweet Lua] (5.1) - C++ 類繫結及函式基於樣版的繫結。(MSVC)
- [lux] - 透過 C++ 樣版及參數超載在編譯期發出函式
- [nlua] - C/C++ 函式『命名空間 lua』繫結、表狀使用、基於樣版(無 boost)
- [LuaWrapper] - 提供 luaW_to<T> 及 luaW_push<T> 等型態安全、直覺的函式,針對任意型別,使使用 Lua 管理 C++ 類別變得簡單的單標頭函式庫。
- [Lutok] - 輕量級 C++ API 使用 Lua。Lutok 在 Lua C API 周圍提供薄 C++ 包裝,以簡化 C++ 和 Lua 之間的互動。這些包裝大量使用 RAII 來防止資源外洩,將 C++ 中友善的資料型態曝露在外,利用例外報告錯誤,並確保在發生錯誤時 Lua 堆疊永遠處於不變狀態。此外,函式庫還在包裝之上,提供少數不同的實用函式。
- [integral] (5.1、LuaJIT、5.2、5.3、5.4) - 無依賴項目的 C++ 函式庫,用於建立 Lua 繫結。
- [lua-intf] (5.1、5.2 & 5.3) - 純 C++11 API 及 Lua 繫結(僅標頭),支援 lua 堆疊 API,一個較高層級的 API,可以像 C++ 類別物件一樣,引用 lua 物件,也可以為 lua 指令碼匯出 C++ 類別及函式。匯出繫結支援自訂 C++ 型別、多個傳回值、C++ 共享指標、輸入/輸出參數,也可以使參數變成選用或預設值。新版本還附帶一個選擇性的 Qt 資料型態對應(QString、QVariant、QByteArray 等)。
- [LuaState] (5.1 & 5.2) - C++11 樣版函式庫(clang、gcc、VS 12)無 boost。為了更簡易好用,且盡可能加快。從 Lua 到 C++ 的基於 lambda 的繫結。
- [輝夜] (5.1 、5.2 、5.3) - 使用 boost 或 C++11 範本函式庫的 C++03。
- [Lua Primer] (5.2、5.3、艾莉絲) - C++11 範本函式庫。它不僅能產生與 lua 的連結,更能支援使用 Lua Eris 進行簡便、無縫的序列化。另請參閱[github]關於 eris 的說明。
- [Ponder] (5.3) Ponder 是 C++ 反射 API,可以揭露聲明給 Lua 的 API。使用容易。
- [自動產生連結] 使用 C++11 範本來推論 C 函式引數,自動產生包裝函式,以揭露本機 C 函式給 lua 程式碼使用。
另請參閱
從 C/C++ 呼叫 Lua
上述架構和文章都是單向連結:從 C/C++ 呼叫 Lua 函式,傳入引數並取得回傳值。
將 Lua 嵌入至 C++
這些架構比先前的架構稍微廣泛一點:它們允許您的 C++ 程式與 Lua 直譯器充分互動,但將擴充 Lua 到其他連結系統 (SWIG、tolua++ 等) 的任務留給它們。
- [lua_icxx]:(發音為 "lua-ix") C++ 的 Lua 直譯器;呼叫 Lua 函式和使用者資料 (類別) 方法、使用表格、建立函式沙盒、使用多個回傳值、評估表達式與指令碼等。連結應用程式 (例如 SWIG 和 tolua++) 的遺失連結。
自動連結產生器
- [toLua] (5.2) - 如果有許多資料需要連結,自動進行連結程序的作業會很有幫助。toLua 就是其中一項工具。準備好套件檔案,這是一個清除過後的 C/C++ 介面版本。使用此技術的另一項優點是如果 Lua C API 有顯著變更,Lua 版本之間需要進行的工作較少。
- [tolua++] (5.1) - tolua 的擴充版本,具備一些針對 c++ 的額外功能。請參閱 CompilingToluappWithoutScons,了解不使用 SCons 編譯 tolua++ 的方式。
- [CPB] (5.0) - Lua 指令碼語言的簡單、快速且強大的連結程式庫。它會從編譯器符號取得資料並直接從中產生連結程式碼。(MSVC)
- [SWIG] (5.0/5.1) - 簡化的封裝程式與介面產生器,它可以在您的 C/C++ 程式與各種指令碼語言 (Python、Perl、Tcl/Tk、Ruby 等) 之間產生連結,其中包括 Lua。最大的優點可能是,針對 SWIG 支援的語言編寫連結時,只會使用 *一個* 介面檔,與 tolua/tolua++ 所使用的介面檔類似。請參閱與 Lua 相關的 SWIG 文件 [5]。
- [luna-gen] - lua 連結程式碼產生器,支援下列功能:內容、繼承 (從 lua 和 c++ 而來)、名稱空間、枚舉、型態檢查、c++ 例外處理、採用政策、g++ 和 MSVS、運算元超載、使用者可設定的使用者定義的字串和數字/枚舉型態等。快速的編譯與執行速度 (比 luabind 和 SWIG 快得多)、人類可讀取的輸出程式碼、沒有 boost 相依性。
- [dub] - 使用 Doxygen 分析 C++ 標頭。支援下列功能:內容、繼承、型別轉換、Lua 封裝、枚舉、例外處理、運算元、使用者定義型別連結、C++ 範本解析、具有錯誤處理功能的 C++ 回呼、具有執行階段型別解析功能的超載方法等。產生程式碼的最佳化目的是使其能儘可能快 (回傳值最佳化、內聯物件等)。
- [Ponder] - 在使用 Ponder 宣告 API 之後,即可自動將其公開到 Lua。Ponder 是 C++ 反射系統,也支援 Lua 連結及 XML/JSON 序號化。
DLL 的代理程式封裝器
可從動態連結函式庫匯出函數資訊。 [FuBi] 說明了一個從腳本 (或 RPC) 呼叫這些函數的方法。這個功能可從 Lua [6] 使用。
雜項
- [wxScript] (5.0) - 一組抽象類別,可為您的 wxWidgets 應用程式/函式庫新增腳本詮釋器支援。
其他語言
Ada
Bash 外殼
luabash 工具是可動態載入的 bash 外殼模組,可在 bash 外殼和 lua 腳本語言之間提供橋樑。這能使複雜的嵌入式程式碼片段替換成高效的 lua 程式碼,並提升外殼腳本的速度,無需大費周章重寫現有程式碼。
Basic
- [FreeBASIC] - 一個開放原始碼的 BASIC 編譯器,附帶 Lua 標頭和函式庫。
- [PBLua] (5.0.2) - 將 Lua 5.0.2 封裝起來的 Purebasic 函式庫。(已棄用)
- [PowerBLua] (5.0) - PowerBASIC 包含和封裝 Lua 的來源 (進行中)。
- [BlitzMax] (5.1.2) - 將 Lua 5.1.2 封裝起來的 BlitzMax 模組 (注意:連結目前指向的是本 wiki (在這個清單中通常是不好的做法),但只要套件有自己的網站就會立即變更)
COBOL
D
- [LuaD] (5.1) - 針對 D 程式語言的 Lua 繫結和高階介面。
- [DLua] (5.1) - 針對 D 程式語言的 Lua 繫結。
Erlang
- [erlua] (5.1) - 目標是在 Erlang 和 Lua 之間啟用無縫的互用性。
- [erl-lua] (5.1) - 允許將 Lua 嵌入 Erlang VM 的 Erlang 連結驅動程式。
- [erluna] (5.1) - Lua 繫結至 Erlang。
Fortran
- [Aotus] (5.3) - 目標是讓 Lua 腳本能順暢地用於設定 Fortran 應用程式,使用 ISO-C-Binding。
- [f2k3-lua] - 透過 Fortran 2003 ISO-C-Binding 和 Lua 互動。
Go
- [golua] (5.1) - 供 Go 使用的 Lua 繫結。
- [luar] (5.1) - 建立在 golua API 上的反射層,提供公開 go 函式至 Lua VM 的簡化方式。
- [go-lua-test](5.1) - 使用各種 Go Lua 繫結的範例
Haskell
- [HsLua] (5.1) - Haskell 的 Lua 指令碼繫結。
Java
- [LuaJava] (5.1) - 允許以 Lua 編寫的指令碼操控透過 Java 開發的元件 (JNI 至原生 Lua),反之亦然。
- [JNLua] (5.2, 5.1) - 另一個 Java JNI <-> Lua 橋接器。包括 JSR 223 提供者 (Java 平台指令碼)。
- [jna-lua] - Java JNA <-> 原生 Lua 橋接器。
- [java-lua] - Java JNI Lua 橋接器。從 Java 呼叫 Lua 以及從 Lua 呼叫 Java 回呼。
LabVIEW
Objective-C
- [LuaObjCBridge] (5.1) - 從 Objective-C 和反向呼叫 Lua (MacOS X Cocoa)。
- [LuaCore] (5.1) - 一個基於 LuaObjCBridge 的架構,可簡化建立並執行 Lua 指令碼。
- [LuaCocoa] (5.1) - LuaObjCBridge/LuaCore 的精神繼承者?,Lua 和 Obj-C 之間的橋接器,並使用 Apple 的 BridgeSupport? 填補非 ObjC 的區域 (例如結構體、C 函式、內嵌函式) 以存取平台上的所有 API。還包括一個適合透過 ScriptingBridge? 用 Lua 寫入 AppleScript?的命令列工具。(Mac OS X)。
- [iPhone Wax] (5.1) - Lua 和所有 Objective-C/Cocoa
Touch 類別之間的橋接器。 - [Objective Lua] (5.1) - 為 Lua 提供類 Objective-C 的語法。
- [TLC] (LuaJIT 2) - 暴露 Objective-C 物件與方法至 Lua 的輕量級 (低於 400 行,純 Lua) 橋接器。
OCaml
- [ocaml-lua] (5.1.x) - 從 OCaml 和反向呼叫 Lua (僅在 Linux 中測試,應可用於 OS X)。
Pascal
Perl
PHP
Python
- LunaticPython [7] (5.1) - Lua/Python 雙向橋接器。允許將 Lua 詮譯器內嵌於 Python 程式中,以及將 Python 詮譯器內嵌於 Lua 程式中。
- [Lupa] (LuaJIT2)(5.1、5.2、?5.3) - 將 Lua 內嵌於 Python。允許在 Python 和 Lua 程式碼之間進行雙向溝通,並盡可能採用兩邊相同的行為。
- ffilupa [8] (5.2、5.3) - Python 和 Lua 之間的現代化雙向橋接器。使用 CFFI 作為後端將 Lua 整合至 Python 中,這兩種都可以快速執行於 CPython 和 PyPy?。靈感源自於 Lupa。
R
- RClient [9] (LuaJIT) - LuaJIT client,適用於用來主機 (當地或遠端) R 會話的 Rserve,因此可以建立連線。此函式庫允許在 LuaJIT 中執行任意的 R 程式。
- 在R會議中,可以透過Python會議作為過渡,利用Lupa(上述提到的Python封裝)+ reticulate(從CRAN內的R包安裝:https://rstudio.github.io/reticulate/),存取Lua程式語言與物件。最好同時檢閱LunaticPython與Lupa中的範例,以了解如何建置和使用這個過渡辦法。
Ruby
Tcl
Terra
[Terra]是一種新的低階系統程式設計語言,旨在與Lua程式設計語言無縫互通。
與C語言一樣,Terra是一種簡單的靜態編譯語言,具備手動記憶體管理功能。但與C語言不同,它是從一開始就設計為與Lua互通。Terra函式是使用terra關鍵字建立的一流Lua值。需要時,它們會JIT編譯成機器碼。
您可以使用Terra和Lua
作為具有高執行效能延伸功能的腳本語言。雖然Lua與其他動態語言的表現持續改善,但低抽象層級可在您需要時預測性地控制效能。
作為軟體DSL的JIT編譯器。使用Lua對Terra進行元程式編寫。允許您將使用Lua編寫的特定領域語言(DSL)編譯成高執行效能的Terra程式碼。將Terra-Lua程式內嵌到其他軟體中作為函式庫,讓您可以在現有的軟體中加入JIT編譯器。
作為獨立的低階語言。Terra的設計使其可以獨立於Lua執行。事實上,如果您的最終程式不需要Lua,您可以將Terra程式碼儲存為.o檔案或可執行檔。在此用例中,Lua作為一種強大的元程式編寫語言。您可以將它視為C++範本元程式編寫的替代方案,具有更好的語法和更友善的屬性。
架構
CORBA
Windows COM
- LuaCom -(5.1/5.0)Lua介面,用於Microsoft的元件物件模型(COM)。從Lua呼叫COM物件,和在Lua中實作COM物件。
Windows .NET
Firefox
- [Moonshine] - Firefox 網頁瀏覽器的嵌入式 Lua 環境。允許使用 Lua 而非 Java
Script 來開發 Firefox 擴充功能。實作為擴充功能 (XPI),使用 XUL、Java
Script 和 C++ 編寫。
XML-RPC / SOAP
另請參閱
RecentChanges · 偏好設定
編輯 · 記錄
上次編輯於 2023 年 6 月 14 日,格林威治標準時間晚間 9:00 (diff)