In C you can't refer to Lua functions directly but you can represent numbers and strings. So, for a function to "be called later", you can store this function in some table and refer to it by a numeric or string key of the table.
Here's a simpleminded mechanism to start with:
On the Lua side:
funcs = {}
local function register_hanlder(key, fn)
funcs[key] = fn
end
register_handler("on_mouse_click", function()
print "You clicked me!"
end)
On the C side:
/* code not tested */
lua_getglobal(L, "funcs");
lua_getfield(L, -1, "on_mouse_click");
if (!lua_isnil(L, -1)) {
lua_call(L, 0, 0);
else {
// nothing registered
}
Instead of registering the functions in a global table you can register them in the registry table (see luaL_ref). You'll get some integer (that's the key in the registry table where the function value is) that you can pass around in you C code.
Note that if you don't need to store a Lua function "for use later" you don't need any of this: if your C function has some Lua function passed to it via argument you can call it outright.
== Edit:
As I mentioned, instead of using a global variable (the funcs
above) you can store the reference to the function in the "registry". Conceptually there's no difference between this method and the previous one.
Let's re-use the previous example: you want the Lua programmer to be able to register a function that would be fired whenever a mouse is clicked in your application.
The Lua side would look like this:
register_mouse_click_handler(function()
print "the mouse was clicked!"
end)
On the C side you define register_mouse_click_handler
:
static int the_mouse_click_handler = 0;
static int register_mouse_click_handler(lua_State* L) {
the_mouse_click_handler = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
(...and expose it to Lua.)
Then, in your application, when the mouse is clicked and you want to call the Lua function, you do:
...
if (the_mouse_click_handler != 0) {
lua_rawgeti(L, LUA_REGISTRYINDEX, the_mouse_click_handler);
lua_call(L, 0, 0);
} else {
// No mouse handler was registered.
}
...
(I may have typos in the code.)