Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

56 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

Originally written by Fabio Mascarenhas, and currently maintained by Craig Presti at here

This corresponds to the latest version 2.0.3, backported to use P/Invoke against standard Lua 5.1 shared libraries. It provides a working version of LuaInterface buildable on Mono.

On Debian/Ubuntu, you will need the liblua5.1-dev and mono-devel packages.

To build, go into the src directory, and:

$ ./configure

This requires a Lua installation to run, but no other dependencies. It will look for the Lua headers in the usual places, /usr/include and /usr/include/lua51, if your Lua directory is somewhere else altogether set LUA_INCLUDE:

$ ./configure LUA_INCLUDE=/home/you/lua-5.1.5/src DEFINES=lua

DEFINES here is overriding the default on Linux, which is to assume the Lua shared library looks like liblua5.1.so rather than lua51.so.

Configuration of LuaInterface is controlled by two C# preprocessor defines, __Windows__ and __liblua__. The first makes the shared library extension '.dll', and the second makes the Lua shared library name 'liblua5.1' rather than 'lua51'. The latter is the default for Linux, at least for Debian/Ubuntu. Look at src/LuaDLL.cs to see how these are used, and how to modify for your configuration.

(Currently, this project builds against Lua 5.1 or LuaJIT.)

$ make
$ ./

Last step assumes you have a ~/bin directory, but you can install globally with

$ sudo ./install /usr/local/bin

(You can also install globally with e.g sudo ./install /usr/local/bin)

It will generate a wrapper script called luai looking like this:

#!/bin/sh
LUAI=/home/azisa/lua/MonoLuaInterface/bin
export LD_LIBRARY_PATH=$LUAI
export LUA_PATH=";;$LUAI/lua/?.lua"
/usr/bin/mono $LUAI/luai.exe $*

We have to locally mess with LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OS X) because LuaInterface will need to find both the Lua shared library and the stub library luanet.so.

The samples directory contains the original samples, plus some extended ones from the Lua for Windows project.

Here is the proverbial 'Hello World':

-- hello.lualuanet.load_assembly"System"localConsole=luanet.import_type"System.Console"localMath=luanet.import_type"System.Math"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

Using the CLRPackage utilities, it is even simpler, since individual classes will be loaded as needed:

-- hello2.luarequire'CLRPackage'import"System"Console.WriteLine("sqrt(2) is {0}",Math.Sqrt(2))

If you want an interactive prompt, then there is a Lua interpreter in Lua, called lua.lua, in the samples directory:

samples$ luai lua.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
lua.lua (c) David Manura, 2008-08
> require 'CLRPackage'
> Console.WriteLine("hello from Mono") -- 'System' is already loaded...
hello from Mono
>

It is straightforward to write GTK# applications in Lua - note that here the import call is passed the package name and the namespace, in cases where they are not the same:

-- hello-gtk.luarequire'CLRPackage'import ('gtk-sharp','Gtk')
Application.Init()
localwin=Window("Hello from GTK#")
win.DeleteEvent:Add(function()
Application.Quit()
end)
win:Resize(300,300)
locallabel=Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
Application.Run()

This automatically creates globals, which is the only way that Lua can mimick the usual C# scope resolution rules. For larger programs, this is probably not a good idea, and so there's a way of explicitly creating namespaces:

-- hello-gtk2.luarequire'CLRPackage'luanet.load_assembly'gtk-sharp'localgtk=luanet.namespace'Gtk'gtk.Application.Init()
localwin=gtk.Window("Hello from GTK#")
win.DeleteEvent:Add(function()
gtk.Application.Quit()
end)
win:Resize(300,300)
locallabel=gtk.Label()
label.Text="Hello World!"win:Add(label)
win:ShowAll()
gtk.Application.Run()

LuaInterface from C#

LuaInterface is usually used by CLR applications which need a scripting language. An example of the high-level interface with Lua is tests/CallLua.cs; this directory also has the original C# tests. (These all pass, except for passing a managed function to string.gsub, which is a Lua limitation.)

A basic C# program is here; it evaluates Lua expressions:

usingSystem;usingLuaInterface;publicclassTestLua{publicstaticvoidMain(string[]args){if(args.Length==0){Console.WriteLine("provide a Lua expression!");}else{LuaL=newLua();// will open all the standard Lua librariestry{object[]results=L.DoString("return "+args[0]);Console.WriteLine("answer is {0}",results[0]);}catch(Exceptione){Console.WriteLine("error: {0}",e.Message);}L.Close();}}}

It must be compiled with a reference to LuaInterface.dll, and both luanet.so and liblua5.1.so must be accessible on the library path.

Lua API

These are contained in the global table luanet:

''luanet.load_assembly''

Loads a CLR assembly; will throw an error if not found.

''luanet.import_type''

Bring in a class using the fully qualified name, e.g. C = luanet.import_type 'System.Console'. The assembly must have been previously loaded.

''luanet.get_object_member''

This is given an object, and an index (string or integer). It can be used to look up a property value, and will return nil + error message if the property does not exist. (Looking up fields and indices directly will fail with an error).

''luanet.make_object''

This takes a table and a CLR class name and allows you to override any virtual methods of that class.

For instance, given this C# class:

publicclassCSharp{publicvirtualstringMyMethod(strings){returns.ToUpper();}publicstaticstringUseMe(CSharpobj,stringval){returnobj.MyMethod(val);}}

then the following Lua code creates a proxy object where MyMethod is overriden:

luanet.load_assembly'CallLua' -- load the assembly containing CSharplocalCSharp=luanet.import_type'CSharp'localT= {}
functionT:MyMethod(s)
returns:lower()
endluanet.make_object(T,'CSharp')
print(CSharp.UseMe(T,'CoOl'))

There is a corresponding luanet.free_object for explicit disposal.

(See tests/CallLua.cs)

In addition, this version of LuaInterface defines two extra functions

''luanet.ctype''

This is the equivalent of typeof in C#; given a class proxy object, return the actual CLR type.

samples $ luailua.luaLua5.1.4 Copyright (C) 1994-2008Lua.org, PUC-Riolua.lua (c) DavidManura, 2008-08>=StringProxyType(System.String): 54267293>ctype=luanet.ctype>=ctype(String)
System.String: 2033388324

''luanet.enum''

This has two forms. The first casts an integer into an enum type:

>enum=luanet.enum>import'System.Reflection'>=BindingFlags.StaticStatic: 8>=enum(BindingFlags,8)
Static: 8

The second form parses a string representation for an enumeration type. This is useful for enum flags:

>=enum(BindingFlags,'Static,Public')
Static, Public: 24

It's now possible to use CLR reflection in a non-clumsy way; see tests/ctype.lua for an example of using the Lua API directly from Lua itself, by importing all static methods of the LuaDLL class.

CLRPackage

This Lua module provides some very useful shortcuts. We have already seen import, which brings classes into the global Lua table. This is not appropriate for larger applications, so there is luanet.namespace. Note that its argument may be a table:

localgtk,gdk=luanet.namespace {'Gtk','Gdk'}

(You do have to explicitly load the assemblies before using this)

''luanet.make_array''

This is a convenience function for creating CLR arrays; it is passed a class (the proxy, not the type) and a table of values.

Note that the Lua expression Class[10] already makes us a Class[] array!

Bear in mind that CLR arrays index from zero, and throw a range error if the index is out of bounds.

''luanet.each''

This constructs a Lua iterator from an IEnumerable interface:

>dd=make_array(Double,{1,2,10})
>forxineach(dd) doprint(x) end1210>import'System.Collections'>al=ArrayList()
>al:Add(10)
>al:Add('hello')
>foroineach(al) doprint(o) end10hello>ht=Hashtable()
>ht.one=1>ht.two=2>forpineach(ht) doprint(p.Key,p.value) endone1two2

About

Mono-buildable version of LuaInterface

Resources

Stars

39 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages