• Announcement: Lua.org now officially recommends this forum as a meeting place for the Lua community
  • The forum is currently open to new registrations. The registration will close for a short period of time when reaching 500 active members, to upgrade the server resources.

Using NLua on .NET (1 Viewer)

What is NLua?​

NLua is a .NET library that allows you to easily integrate Lua in your C# application, calling Lua functions, reading Lua tables or calling C# methods from within Lua scripts. NLua is actually a fork of the project called LuaInterface from Craig Presti/Fabio Mascarenhas so most of features and documentation you find from LuaInterface should work with NLua.

Why you would want to use Lua on .NET?​

You could use Lua to script parts of your application, allowing to quickly change behavior without having to rebuild your application. Scenarios like games, customization, extensions.

How to use NLua?​


Install-Package NLua

  • Add NLua namespace:
Code:
using NLua;

  • Create a state object:
Code:
Lua state = new Lua()

  • You can pass objects from C# to Lua context using the [] operator, you can pass strings, numbers, delegates, objects
Code:
state["var1"] = "someValue";

Here is a full example of an application passing values back and forth:

Code:
using System;
using NLua;
namespace TestNLua
{
    class MyClass
    {
        public int IntegerProperty { get; set; }
        public void DoSomething(string p)
        {
            Console.WriteLine($"Doing something: {p}");
        }
    }
    class MainClass
    {
        static Lua state;
        public static double Compute(double x)
        {
            return x * (x - 1);
        }
        public static void Main(string[] args)
        {
            var myobj = new MyClass();
            myobj.IntegerProperty = 17;
            state = new Lua();
            state["var1"] = "someValue";
            state["obj"] = myobj;
            state["compute"] = new Func<double, double>(Compute);
            // Will print "output: someValue"
            state.DoString(" print('output: ' .. var1) ");
            // Will print 18
            state.DoString(" print(obj.IntegerProperty + 1) ");
            // Will print "Doing something: hello"
            state.DoString(" obj:DoSomething('hello') ");
            // Will print "-0.1875"
            state.DoString(" print(compute(0.25)) ");
            // Reading values back
            state.DoString(" x = compute(0.75) ");
            state.DoString(" y = 2.0 * (obj.IntegerProperty * x) ");
            double x = state.GetNumber("x");
            double y = state.GetNumber("y");
            // Will print: x = -0.1875, y = -6.375
            Console.WriteLine($"x = {x}, y = {y}");
        }
    }
}


Which platforms are supported?​

NLua supports Windows/ UWP, Linux, macOS, iOS/tvOS/watchOS, Android.

How it works?​

NLua uses KeraLua which is a low-level binding for the Lua C API, KeraLua binding 1:1 every function from Lua C API.

Which version of Lua KeraLua is using?​

KeraLua package uses the latest version of Lua (5.4.2)

What about NeoLua, MoonSharp?​

Those are good libraries, I guess people that can't use p/Invoke can use those as alternatives. The performance can be very poor, and most of those libraries try to be compatible with Lua. I believe instead of reinventing the wheel is better just to use the battle tested Lua library. Lua has been developed for almost 28 years, so it would be a waste to try to rewrite it.

gist: NLuaPost.md
 

dinsdale247

Moderator
Staff member
Community Patron
Creator of WinLua
Joined
Nov 17, 2020
Messages
69
Reaction score
27
Location
Victoria BC
Website
winlua.net
Hurray! Thanks @viniciusjarina. I've used both NLua nd NeoLua very effectively for different things. I wanted to do a "shoot out" style article with the two packages, but the full article will have to wait. Here are my experiences with NLua and NeoLua.

NLua
I am a HUGE fan of this package. I was so relieved when you picked development back up because I was struggling to figure out how to write my own (or salvage an existing one).

(Note: the following opinion is all based on 5.3 compatible runtimes. I tinkered with NeoLua that had some early 5.4 support, but not much. This work was done some time ago so my details *may not be quite right*. If something is said in error, I apologize and will correct it.)

Where I have used NLua: My biggest success was using NLua with a C# serial port library. NLua gave me the ability to add scripts to the application so someone can script a conversation with an embedded system. It was great because I could write the extensions I needed in C/C++ using mingw (The end users are windows users) and get really great performance and even re-use communications modules with the embedded system (re-use never happened unfortunately).

I've actually done a prototype of a serial port tool with NeoLua as well, but NLua made more sense. I didn't have any performance issues with NeoLua, but NLua was consistently faster by 10-20% (depending on how much processing we were doing), but sometimes only as much as a few percents. I am "working on" a serial port console as an open source project for NLua with DotNet Core.

NeoLua
NeoLua is written against the DotNet scripting runtime. This is very cool because you don't really have two stacks so using a "dynamic" instance of the Lua state is seamless to your C# code. Don't get me wrong, NLua is effortless as well, but NeoLua literally shares the same memory as the main application.

NeoLua has some minor drawbacks. There are some minor differences with regular lua and the error messages are different so you will need to learn what they mean. NeoLua is not compatible with C, but it can include .net Dlls (So NeoLua would need wrappers, I never tried this). By contrast, NLua returns (mostly?) standard error messages and can use both .Net Dlls and C/C++ shared objects (DLL/so depending on platform).

Where I have used NeoLua: I have used NeoLua in a proprietary application that needs to open, modify and send custom configurations to tiny remote embedded systems via a medical device radio. I use it for (almost) all application configs instead of XML or whatnot. The application graphs data output and I was going to add a function that performed custom filtering on the data sets. That feature was never completed.

NeoLua was important here because I will not be maintaining that application. I felt the tighter coupling with the DotNet runtime was a much more compelling feature then being tightly aligned with the Lua.org ABI.

I have used NeoLua to add some (rather crappy) functionality to the WinLua MSI installer. I could have used NLua but I wasn't interested in going there as the entire functionality is a little unsavory.

Performance
I wouldn't say the performance of NeoLua was poor. That wasn't my experience. I was able to perform limited processing on a serial data stream all the way up to ~100 bytes every 35 ms (that figure is from memory).

@viniciusjarina is correct though: For raw performance of the scripts, NLua is faster. There seems to be certain tasks that NLua really shines at and in some scenarios the performance of NLua was very high compared to NeoLua. I don't currently have any numbers to back that up unfortunately. I share @viniciusjarina's opinion the performance of NLua is due to the optimizations afforded to 28 years of development and using the Lua pure C vm/runtime.

Using NLua I was also able to optimize some tasks by performing them in C. While I never took this to the fullest extent possible, I can see where you could create some really fast plugins for an application.

Compatibility
NLua is drop in ready for your existing Lua scripts. NLua is available using Nuget and updates simple from Any Visual Studio or the Nuget command line.

If you need LuaRocks (for modules) or an external interpreter for writing code, I recommend downloading my WinLua package, which contains Lua, LuaRocks and a C/C++ toolchain. I tested NLua/WinLua with a prototype app that used the LuaRocks "Project" level tree as a bundle for a C#/NLua application (project is not on git).

[Author note: WinLua works well with VS Code. I use EmmyLua and the xmake plugin. Using VS Code gives you one IDE for all development.]

NeoLua is available through Nuget as well. Existing scripts may not work and will need to be tested and may need to be modified for NeoLua; especially if they include C/C++ components. There are also some other caveats but I don't remember all the details. NeoLua *does* include some very nice tools for serialization and various tasks that are not available through standard Lua, but that means your scripts may only be compatible with your application. That may or may not be an issue for you.

Conclusion

There are many, many details in the implementation of the two libraries that are of interest, but I don't have time to write that article at the moment (trying to cross build python for a new WinLua Debugger plugin for IDEs...ugh). Regardless of those details, NLua is a premier piece of technology that allows developers to easily integrate Lua and any DotNet flavour. If I was trying to come up with something flashy to say it would be: All developers integrating Lua and C# can benefit from using NLua, but Lua and C/C++ developers will especially appreciate the lua.org runtime. It is very easy to recommend NLua.

Special Thanks

I'd like to thank @viniciusjarina again for his work on the NLua package. I have been professionally successful because of his work. I will note that he also provided me a CMake script for including Lua in a CMake build. His work was used in a number of places on the "Canadian Emergency Ventilator" project: Winnipeg Ventilator receives interim approval | Canadian Healthcare Technology


dinsdale
 
Last edited:
Top