2006/10/02

Lua, Lua... Oh no! Me gotta go

Been messing around with Lua a bit the last few days. Can't remember how I came across it but it's performance against other languages (1, 2) made me decide to give it a serious look. Particularly given how well it did against the dark lord Perl and my personal favorite, Python. Found several other things where people remarked how easy it was to embed in C/C++ programs so I figured it was worth the time.

Downloaded the 5.1.1 source from www.lua.org and had it compiled under cygwin in a matter of seconds without any problems. Found a decent selection of tutorials, and an online version of Programming in Lua but found they were a bit thin when it came to embedding Lua in C. Thought I hit the jackpot with this writeup at debian.org but was amazed to find out that it no longer worked despite being less than a year old.

After an hour or two of (re-)reading the sources above, looking at header files, etc. I was able to figure out enough to get a demo working. It's pretty slick. You can write a C program like:

#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int
main( int argc, char ** argv ){
int value = 1;

// Initialize Lua
lua_State *L = lua_open();

// Load various Lua libraries
luaopen_base( L );
luaopen_table( L );
//luaopen_io( L ); // Not sure why but I get a PANIC if i try to load this
luaopen_string( L );
luaopen_math( L );

luaL_loadfile( L, "3.lua");
lua_pcall( L, 0, 0, 0 ); // Have to parse it once or getglobal() will fail

printf( "C: value is %d\n", value );

lua_getglobal( L, "test" );
lua_pushnumber( L, value );
lua_pcall( L, 1, 1, 0); // 1 argument, 1 result
value = (int)lua_tonumber( L, -1 ); // Lua arrays are 1-indexed /boggle

printf( "C: value is %d\n", value );

// Cleanup
lua_close( L );

return 0;
}


And then you create a script called 3.lua like:
function test (x)
return (x + 1)
end


And your output should be:
C: value is 1
C: value is 2


Pretty slick. Doesn't make the C program terribly huge, either. The luaopen_*() functions load libraries which naturally increase the size of executable. The plain C executable was about 8k, with the four libraries above about 130k, or with just "base" alone it was 114k. OK, OK, so the executable is about 12x larger... it's still neat seeing as how you now have full access to a fairly powerful scripting engine without having to recompile.

I'm positive I can put this to good use in at least one of my projects. Why do I mention it here? Saw a bunch of comments about it being used for scripting, etc. in various video games.... good stuff.

No comments: