在 Lua C API 中,我可以使用lua_tostring()
.
如何通过 Lua API 将 Lua 函数的“引用”(如果这是正确的术语)传递给 C?因此,它可以稍后从 C 中调用,使用lua_call()
,而不必通过它的名称来引用它。
(确实需要这样,C程序将来会在某个地方调用该函数,而程序对该函数一无所知,因为要传递的函数是在Lua程序中定义的)
在 C 语言中,您不能直接引用 Lua 函数,但可以表示数字和字符串。因此,对于“稍后调用”的函数,您可以将此函数存储在某个表中,并通过表的数字或字符串键来引用它。
这是一个简单的机制:
在 Lua 方面:
funcs = {}
local function register_hanlder(key, fn)
funcs[key] = fn
end
register_handler("on_mouse_click", function()
print "You clicked me!"
end)
在 C 侧:
/* 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
}
您可以在注册表中注册它们,而不是在全局表中注册函数(参见 luaL_ref)。您将获得一些整数(这是函数值所在的注册表中的键),您可以在 C 代码中传递这些整数。
请注意,如果您不需要存储“供以后使用”的 Lua 函数,则不需要任何这些:如果您的 C 函数有一些通过参数传递给它的 Lua 函数,您可以直接调用它。
== 编辑:
funcs
正如我所提到的,您可以将对该函数的引用存储在“注册表”中,而不是使用全局变量(上述)。从概念上讲,这种方法与前一种方法没有区别。
让我们重用前面的例子:您希望 Lua 程序员能够注册一个函数,只要在您的应用程序中单击鼠标,就会触发该函数。
Lua 端看起来像这样:
register_mouse_click_handler(function()
print "the mouse was clicked!"
end)
在 C 端,您定义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;
}
(......并将其暴露给 Lua。)
然后,在您的应用程序中,当单击鼠标并要调用 Lua 函数时,您可以:
...
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.
}
...
(我可能在代码中有拼写错误。)