Lua从参数中获取函数

Lua get function from argument

本文关键字:获取 函数 参数 Lua      更新时间:2023-10-16

一个简单的例子。

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

现在在c中,我想获得args #1, #2中的函数。
在字符串,数字,…我们可以得到他们使用(lua_getstring,..),但我至少没有找到如何获得一个函数。

int luaProtocolOnConnect(lua_State* L)
{
    int base_func // func #1
    int call_func // func #2
    ....
}

你不能真正"得到"一个Lua函数。与Lua表一样,Lua函数也是纯Lua对象。因此,它们没有C或c++的类似物。如果你想调用一个Lua函数,可以通过lua_call, lua_pcall或者类似的函数来实现。这是在Lua栈上就地完成的。

所以你不能把一个Lua函数转换成一个c++值。你可以做的是获取一个Lua函数,并以所有Lua对象都可以操作的各种方式操作它。

例如,假设你想在一个c++对象中存储一个Lua函数,然后调用存储在那里的Lua函数。很明显,你不能把Lua函数直接转换成c++值。可以做的是将Lua函数存储在c++可以访问的地方。您使用一些具有c++类比的值来引用存储的Lua函数。对于像这样存储的每个对象,该值必须是唯一的。存储对象时得到的值将保存在c++对象中。当需要检索Lua函数时,您只需使用存储的值来检索它。

因为这是一个非常常见的操作,所以Lua有方法来简化它。第一个是Lua注册表,一个c++可以访问但Lua代码不能访问的表(除非你给它访问权)。

第二个是luaL_ref系列函数。luaL_ref获取堆栈顶部的任何内容,并将其粘贴到您提供的表中,返回给您一个整数键,可用于稍后检索它。lua_rawgeti可用于通过键从表中检索函数,luaL_unref获取表和整数键,在完成后从表中删除所引用的函数。

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

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