C++ 使用可变模板从Lua函数回调(capi)中提取参数
我试图编写一个类,提取从Lua函数调用(Lua脚本调用已注册的C函数)传递的参数,并将其传递给已注册的方法(代码段中的IDelegate),以便执行它并返回值 假设我从GameBoard类注册以下方法:C++ 使用可变模板从Lua函数回调(capi)中提取参数,c++,templates,lua,variadic-templates,C++,Templates,Lua,Variadic Templates,我试图编写一个类,提取从Lua函数调用(Lua脚本调用已注册的C函数)传递的参数,并将其传递给已注册的方法(代码段中的IDelegate),以便执行它并返回值 假设我从GameBoard类注册以下方法: long int游戏板::testFunct(long int)为Lua下的“GB:testFunction”,代码如下: luaL_newmetatable(mState, "GameBoard"); lua_pushstring(mState, "__index"); lua_pushval
long int游戏板::testFunct(long int)代码>为Lua下的“GB:testFunction”,代码如下:
luaL_newmetatable(mState, "GameBoard");
lua_pushstring(mState, "__index");
lua_pushvalue(mState, -2);
lua_settable(mState, -3);
lua_pushstring(mState,"testFunction");
hbt::IDelegate<I32,I32>* ideleg = new MethodDelegatePtr<GameBoard,I32,I32>( NULL, &GameBoard::testFunct); // will be deleted later
lua_pushlightuserdata (mState, (IDelegate<I32,I32>*)ideleg);
lua_pushcclosure(mState, LuaCall<I32,GameBoard,I32>::LuaCallback,1);
lua_settable(mState,-3);
下面是我如何使用它:
// Specialized template returning an integer
template <class C, class... Args>
struct LuaCall<int, C, Args...>
{
static int LuaCallback(lua_State *L)
{
//-- retrieve method "IDelegate" from Lua stack etc.
//-- then call tUnpackLuaArgs with the arguments to push the returned value onto the lua stack
lua_pushnumber(L, tUnpackLuaArgs< sizeof...(Args) >::unpack(funcPtr,L));
return 1;
}
};
//返回整数的专用模板
模板
卢卡尔结构酒店
{
静态int LuaCallback(lua_State*L)
{
//--从Lua堆栈等中检索方法“IDelegate”。
//--然后使用参数调用tunpackluargs,将返回的值推送到lua堆栈上
lua_pushnumber(L,tUnpackLuaArgs:unpack(funcPtr,L));
返回1;
}
};
事实上,如果我从unpack
函数中的if/else中删除LUA\u TSTRING
和LUA\u TBOOLEAN
,它确实可以编译并且工作得很好。事实上,如果您的代码包含例如tunpackluargs::unpack
,那么unpack
的主体将急切地实例化所有可能性(因为它们都可能在运行时到达,这取决于Lua堆栈上参数的类型)
这包括例如tUnpackLuaArgs::apply
,这意味着当Args
为例如long int
时,您会遇到错误,因为std::string
无法转换为IDelegate
的运算符()
所期望的long int常量
实际上,您并不需要所有这些可能性:您已经知道您所期望的是什么(比如您的示例中的long int
)。在需要long int
时提取std::string
是没有用的。因此,您应该尝试从Lua堆栈中提取您所期望的内容(如果转换不起作用,可能会出错,直到运行时才知道).注意,在实例化tUnpackLuaArgs::unpack
之后,实例化的数量大约是N^d,其中d根据您的代码至少是3。为了避免这种情况,您最好在编译时间上做得更好。我仍然不知道如何提取这些参数,但您的解释很清楚,并确认了正确性我被怀疑是这个问题的始作俑者。谢谢。@Valkea您可能对不使用递归的元组感兴趣(有时在不涉及元组的情况下也很有用)。请注意,这里不可能使用递归。
// Specialized template returning an integer
template <class C, class... Args>
struct LuaCall<int, C, Args...>
{
static int LuaCallback(lua_State *L)
{
//-- retrieve method "IDelegate" from Lua stack etc.
//-- then call tUnpackLuaArgs with the arguments to push the returned value onto the lua stack
lua_pushnumber(L, tUnpackLuaArgs< sizeof...(Args) >::unpack(funcPtr,L));
return 1;
}
};