joi, 22 iulie 2010

Lua2C, an updated version

I know I have been "missing in action" lately but I am working furiously, and I seem to have too little time for my blog (very sad face). But, just for a breath of fresh air, I thought I'd share something with the world.

Entering lua2c.lua


Lately I became quite interested in Lua (a lot actually). It has phenomenal speed, exceptional interfacing with C and some features and libraries that just make my day (i.e. coroutines, lpeg, lua-ev and others), and since I needed to embed some Lua scripts (entirely) in a C project I'm currently working on, I ended up adapting Mike Edgar's "bin2c.lua" script (which takes a Lua script and turns it into a C header file) to suit my needs.

Basic functionality


Specifically, this adaptation generates a function that takes a Lua state as the only argument and then runs the embedded Lua code in the given state after which it returns the status (as opposed to putting the code straight in the top-level scope of the generated file). This makes it easier to embed code in C and then invoke it, and also to apply the same code onto multiple Lua states (e.g. multiple threads).

Check the end of the post for a usage sample.

Options



  • [cci_bash]-c[/cci_bash] compiles to Lua bytecode for (slightly) faster loading (does not work with LuaJIT)

  • [cci_bash]-s[/cci_bash] minifies the source code before embedding to minimize wastes

  • [cci_bash]-e[/cci_bash] applies a mild (XOR-based) obfuscation to prevent embedding of plain text

  • [UPDATE: [cci_bash]-u[/cci_bash] produces a (void) function that never fails and panics on errors ]



Download


So here it is, enjoy: lua2c.lua (MIT license, same as Lua)
[UPDATE: It seems that Codecolorer (or GeSHI) totally trashes my script (breaks comments, escapes etc.) so I had to remove the embedded source and instead just post a download link. ]

Just to be clear


For example, given a lua script file called 'test.lua' (shown below) this is how we would go about embedding it into a simple C program called 'test.c'.
[ccn_lua]
-- test.lua: a small sign that we're up and running...

print("I am an embedded Lua script running inside a C binary! Hmm... cozy!")

function some_activity()
-- ...
end

-- ...
[/ccn_lua]

And here is the C file (rather overly commented)...
[ccn_c ]
/*
* Include our embedded script.
*/
#include "test.h"

/*
* Invoke the script.
*/
int main(int argc, char* argv[]) {

// create a Lua state
lua_State* L = lua_open();

// load basic libraries into state
luaL_openlibs(L);

// invoke embedded script into state
// by calling the generated function
load_test_lua(L);

// finish
lua_close(L);
return 0;
}
[/ccn_c]
And here's how we can compile all this into an executable. Note that I tested this on Ubuntu Lucid and the following packages had to be installed: lua5.1, liblua5.1-0-dev, liblua5.1-lpeg2, liblua5.1-bitop0. Your configuration may differ, and if you don't have the pre-built Lua packages, you will have to install them manyally (along with the dependencies)!
[cc_bash]
# generate (unprotected, minified and encrypted) C code
lua lua2c.lua -seu test.lua > test.h

# compile C program against Lua library
gcc test.c -o test `pkg-config lua5.1 --libs --cflags`

# run program
./test
I am an embedded script running from inside a C binary! Hmm... cozy!
[/cc_bash]
Let me know if it works fr you, or if you think of some cool improvement! :D
Cheers!

Niciun comentariu:

Trimiteți un comentariu