Lua Interface

lua-users home
wiki

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 6:25 am GMT (diff)