获取存储在C中的Lua函数的“指针”

在 Lua C API 中,我可以使用 lua_tostring() 将栈中的数字或字符串存储起来。

如何通过 Lua API 将 Lua 函数的“引用”(如果这是正确的术语)传递给 C?这样它就可以稍后通过 lua_call() 从 C 中调用,而无需按名称引用它。

(实际上需要这样,因为 C 程序将在未来的某个地方调用该函数,并且该程序不知道该函数的任何信息,因为要传递的函数在 Lua 程序中定义)

点赞
用户1560821
用户1560821

在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端:

/* 未经测试的代码 */
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.
}
...

(我可能会有代码中的拼写错误。)

2014-05-22 06:20:02