Lua Interface |
|
-- It should also be noted that this works on the Mono runtime http://www.mono-project.com on Linux.
local a = SomeType[5] for i = 1,a.Length do print(i, a[i - 1]) -- .NET arrays are zero-based. end
When using the CLR from Lua, the ordinary method of loading types and classes can seem a little verbose:
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)
It would be nice if syntax like this could be used:
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)
Optionally, the .NET types can be made to appear as toplevel names:
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)
It should not be necessary to make every type name toplevel:
require "net" System = net.System local form1 = System.Windows.Forms.Form() local button1 = System.Windows.Forms.Button() button1.Location = System.Drawing.Point(10, 10)
Here is the method:
-- 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