Lua 获取参数中的函数

一个简单的例子,用于生成如下代码:

protocol.onConnect(function() end, function () end, ...)

现在在 C 中,我想获取参数 #1、#2 中的函数。

在字符串、数字等数据类型中,我们可以使用 (lua_getstring,..) 等方式获取它们,但是我至少没有找到如何获取函数的方法。

int luaProtocolOnConnect(lua_State* L)
{
    int base_func // func #1
    int call_func // func #2
    ....
}
点赞
用户1442917
用户1442917

你可以使用 lua_isfunction 来检查它是否是一个函数,使用 lua_pushvalue 将其值推到堆栈的顶部,然后使用 luaL_ref (luaL_ref(L,LUA_REGISTRYINDEX);) 将其转换成一个唯一的键,稍后可以引用该键来检索值 (lua_rawgeti(L,LUA_REGISTRYINDEX,ref)) 并调用函数。

2016-07-02 04:40:59
用户734069
用户734069

你无法真正“得到”一个 Lua 函数。Lua 函数和 Lua 表一样是纯 Lua 对象。因此,它们没有 C 或 C++ 的类比。如果你想调用一个 Lua 函数,可以通过 lua_calllua_pcall 或类似的函数来实现。这是在 Lua 栈上实现的。

因此,你无法将 Lua 函数转换为 C++ 值。你能做的是以各种方式操纵 Lua 函数,就像操纵所有 Lua 对象一样。

例如,假设你想在 C++ 对象中存储一个 Lua 函数,然后稍后调用存储在那里的任何 Lua 函数。显然,你无法直接将 Lua 函数转换为 C++ 值。你可以将 Lua 函数存储在 C++ 可以接受的位置。你需要使用某个值来引用存储的 Lua 函数,该值必须对于你想要存储的每个对象都是唯一的。当你存储对象时所得到的值将保存在你的 C++ 对象中。当需要检索 Lua 函数时,只需使用存储的值来检索。

因为这是一种非常常见的操作,Lua 有办法简化这个操作。第一个是 Lua 注册表,它是 C++ 可以访问的表,但 Lua 代码不能访问(除非你允许它)。

第二个是 luaL_ref 系列函数。luaL_ref 将堆栈顶部的任何内容放入你提供的表中,并返回一个整数键,该键可用于以后检索它。lua_rawgeti 可以用来通过键从表中检索函数,luaL_unref 可以用来从表中删除引用的函数。

因此,如果你想存储这样的函数,只需要创建这样的一个表,并将其置于注册表的已知位置(以便在需要时可以获取它),然后使用 luaL_ref 存储这些函数。当需要调用它们时,使用 lua_rawgeti 检索它们。当你完成使用它们时,使用 luaL_unref 销毁它们。

2016-07-02 04:45:36