Lua Interface |
|
Interface 是一個用於 Lua 語言和 Microsoft .NET 的通用語言執行時期 (CLR) 之間整合的程式庫。Lua 腳本可以使用它來實例化 CLR 物件、存取屬性、呼叫方法,甚至是使用 Lua 函式處理事件。網站
相依性: .NET。在 Linux 上的 Mono 執行時期 http://www.mono-project.com 也可以運作。
注意:版本 1.5.3 建立了一個 C 模組 DLL,可以載入一般的 Lua 詮譯器中。版本 2.0 以上是完全受控的程式碼。 [4][5][6][7][2][3]
未在 LuaInterface 文件中提到的是如何實例化 .NET 陣列。這個動作可透過使用數字索引類型參考來完成
local a = SomeType[5] for i = 1,a.Length do print(i, a[i - 1]) -- .NET arrays are zero-based. end
使用 Lua 從 CLR 載入類別和型別的常見方法看起來有些不言自明
net = require "luainterface" net.load_assembly("System.Windows.Forms") net.load_assembly("System.Drawing") Form = net.import_type("System.Windows.Forms.Form") Button = net.import_type("System.Windows.Forms.Button") Point = net.import_type("System.Drawing.Point") local form1 = Form() local button1 = Button() button1.Location = Point(10, 10)
可以使用此類語法會比較好
require "net" Form = net.System.Windows.Forms.Form Button = net.System.Windows.Forms.Button Point = net.System.Drawing.Point local form1 = Form() local button1 = Button() button1.Location = Point(10, 10)
.NET 型別可以選擇顯示為頂層名稱
require "net" System = net.System Form = System.Windows.Forms.Form Button = System.Windows.Forms.Button Point = System.Drawing.Point local form1 = Form() local button1 = Button() button1.Location = Point(10, 10)
不需要將每個型別名稱都變成頂層
require "net" System = net.System local form1 = System.Windows.Forms.Form() local button1 = System.Windows.Forms.Button() button1.Location = System.Drawing.Point(10, 10)
方法如下
-- Create a metatable for our name components local metatable = { [".NET"] = {getmetatable=getmetatable} } -- Load LuaInterface local g = getfenv(0) setfenv(0, metatable[".NET"]) local init, e1, e2 = loadlib("LuaInterfaceLoader.dll", "luaopen_luainterface") assert(init, (e1 or '') .. (e2 or '')) init() setfenv(0, g) -- Lookup a .NET identifier component. function metatable:__index(key) -- key is e.g. "Form" local mt = getmetatable(self) local luanet = mt[".NET"] -- Get the fully-qualified name, e.g. "System.Windows.Forms.Form" local fqn = ((self[".fqn"] and self[".fqn"] .. ".") or "") .. key -- Try to find either a luanet function or a CLR type local obj = luanet[key] or luanet.import_type(fqn) -- If key is neither a luanet function or a CLR type, then it is simply -- an identifier component. if obj == nil then -- It might be an assembly, so we load it too. luanet.load_assembly(fqn) obj = { [".fqn"] = fqn } setmetatable(obj, mt) end -- Cache this lookup self[key] = obj return obj end -- A non-type has been called; e.g. foo = System.Foo() function metatable:__call(...) error("No such type: " .. self[".fqn"], 2) end -- This is the root of the .NET namespace net = { [".fqn"] = false } setmetatable(net, metatable) -- Preload the mscorlib assembly net.load_assembly("mscorlib") return nil