Lua Interface


LuaInterface is a library for integration between the Lua language and Microsoft .NET's Common Language Runtime (CLR). Lua scripts can use this to instantiate CLR objects, access properties, call methods, and even handle events with Lua functions.

Web sites:

Dependencies: .NET. Also works on the Mono runtime http://www.mono-project.com on Linux.

Note: Version 1.5.3 builds a C module DLL that can loaded in regular Lua interpreter. Version 2.0 and above are completely managed code. [4] [5] [6] [7] [2] [3]

User Comments

Not mentioned in the LuaInterface documentation is how to instantiate .NET arrays. It is done simply by indexing a type reference with a number:

local a = SomeType[5]
for i = 1,a.Length do
	print(i, a[i - 1]) -- .NET arrays are zero-based.
end


[ LuaInterface-1.3.0 adds the following feature ]

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

See Also


RecentChanges · preferences
edit · history
Last edited July 26, 2011 1:25 am GMT (diff)

AltStyle によって変換されたページ (->オリジナル) /