Sep 29 |
Embedding Lua and C# |
I make it a point to learn 2 new programming languages each year; this year I have learned Flex/ActionScript and Lua.
I already have a few blog posts about my work in Flex, specifically integration between Flex and .NET. I would now like to introduce you to Lua and demonstrate it’s embedding features in C#.
What is Lua?
In a nutshell, Lua is a fast, light-weight scripting language that is extremely portable (it can be built on any platform with an ANSI C compiler.) Lua is considered the fastest interpreted scripting language, and is highly embeddable, in fact; I first came into contact with Lua while working on an open source project that is primarily written in C++ but is currently being extended by Lua.
Getting started
Before we get our hands dirty writing code, we will need to get LuaInterface.dll, a library for integration between Lua and the CLR. You can get the LuaInteface here: http://luaforge.net/projects/luainterface/ or you can get it via SVN here: http://luainterface.googlecode.com/svn/trunk and compile it yourself.
Time to embed!
Step 1: Lets create a basic C# application, import the LuaInterface namespace, and create a Lua object interpreter object.
using LuaInterface;
class Foo
{
static void Main(string[] args)
{
Lua lua = new Lua();
}
}
At this point, we have a working lua interpreter embedded into our application; we can execute any lua string or lua file. Take this code for example:
string lua_loop = "for i=0,10 do print(i) end"; lua.DoString(lua_loop);
will print number 0-10, to the console, not super fascinating, but we are getting there…You can also execute entire Lua files by:
lua.DoFile("d:\bin\foo.lua");
Time to really embed!
So far I have shown you how to get a Lua interpreter running in a C# application and how to run strings of Lua in the embedded interpreter. Lets kick it up a notch and call C# functions via Lua.
Say we want to expose the following C# function that performs the SHA1 hash to Lua…
public string SHA1(sting text) {
string hash = null;
using(SHA1 sha = new SHA1CryptoServiceProvider()) {
byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(text));
hash = Convert.ToBase64String(result)
}
return hash;
}
All we need to do is hook the SHA1 function into Lua by the RegisterFunction function; whew, that was a mouthful. Here it is in code:
class Foo
{
static void Main(string[] args)
{
Foo foo = new Foo();
Lua lua = new Lua();
// registers the C# function with the Lua interpreter.
lua.RegisterFunction(”SHA1″,foo,foo.GetType().GetMethod(”SHA1″));
// we can now call SHA1 from Lua.
lua.DoString(”print SHA1(’gork’)”);
}
public string SHA1(sting text) {
string hash = null;
using(SHA1 sha = new SHA1CryptoServiceProvider()) {
byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(text));
hash = Convert.ToBase64String(result)
}
return hash;
}
}
In this example I just called the function via the DoString function however, I could have just as easily execute SHA1 from a Lua script.
The Lua interpreter object can also be used as an indexer to pass data between Lua and C#, the following code snippets demonstrates:
// creates a global Lua variable 'foo' with value 'gork' lua["foo"] = “gork”; // converts Lua global variable back to C# variable. string foo = (string)lua["foo"];
Putting it all together, we can perform the SHA1 hash in Lua and get a handle to our result:
// perform a SHA1 hash in Lua with a C# function.
lua.DoString("hash = SHA1('gork')");
string hash = (string)lua["hash"];
System.Console.WriteLine(hash);
There are certainly more things that can be done between Lua and C#, but I feel like this is a straightforward introduction that may spark some interest, so I am going to leave it at that. Until next time, happy hacking.











May 25th, 2009 at 4:53 pm
Coming back again to reread your article and it makes more sense. I have been experimenting with Lua a great deal and am hitting some snags. I can’t seem to find good resources on continuing with my pet project. What does the Lua script look like once you have registered a C# function with Lua? This would be awesome if I could get just a step closer.
Thanks in advance…
David