For those not in the know, Lua is an excellent (fast!) embeddable programming language. It supports a wide range of features, from the usual first-order functions and garbage collection all the way to closures. Its most maor redeeming feature, though, is the fact that (unlike, say, Python) it is designed to be embedded: its interoptability with the host program is extremely good.

It has its fair share of drawbacks, of course (for one thing, it doesn't have += or similar unary operations . . .), but the main one is that Lua has a C API. This isn't a huge issue, but it does make using it in C++ a little bit more awkward than it perhaps should.

For example, let's say you want to bind a function to global scope. Well, it's easy if you have a static function:

/* have lua_State *lua from above */
lua_pushfunction(lua, funcName);
lua_setglobal(lua, "globalname");

But what about a member function? Doesn't work, unfortunately, because Lua wants a lua_CFunction. Well, here's one way to do it: enter Boost.

Here's a trick: use boost::bind to create a boost::function object that has the first parameter bound to an object instance, and then call the boost::function. Using Lua userdata and metatables, it's simplicity itself:

typedef boost::function<int (lua_State *)> FType;

/* ... */

FType f = boost::bind(&ClassName::function, cn, _1);
void *memory = lua_newuserdata(lua, sizeof(f));
/* placement-new, google it if you don't know it. */
new (sizeof(f)) FType(f);
lua_newtable(lua);
lua_pushcfunction(lua, dispatcher);
lua_setfield(lua, -2, "__call");
lua_setmetatable(lua, -2);

/* ... */

static int dispatcher(lua_State *lua) {
    FType *f = lua_touserdata(lua, 1);
    /* TODO: remove first argument . . . */
    return (*f)(lua);
}

And there you go. There are a few things missing here:

Happy hacking,

- ethereal