一个简单的生产例子。
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
....
}
答案 0 :(得分:3)
您可以使用lua_isfunction检查它是否为函数,使用lua_pushvalue
将其值放在堆栈顶部,然后使用luaL_ref(luaL_ref(L,LUA_REGISTRYINDEX);
)转它成为一个唯一的密钥,您可以在以后引用它来检索值(lua_rawgeti(L,LUA_REGISTRYINDEX,ref)
)并调用该函数。
答案 1 :(得分:3)
你真的不能"得到" 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
获取表和整数键,当你完成它时,从表中删除引用的函数。
因此,如果您想存储此类函数,只需创建一个这样的表,将其粘贴在注册表中的已知位置(以便您可以在需要时随时获取),然后使用{{1}存储这些功能。在调用它们时,请使用luaL_ref
检索它们。当您使用完毕后,请使用lua_rawgeti
销毁它们。