Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用可变模板从Lua函数回调(capi)中提取参数_C++_Templates_Lua_Variadic Templates - Fatal编程技术网

C++ 使用可变模板从Lua函数回调(capi)中提取参数

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

我试图编写一个类,提取从Lua函数调用(Lua脚本调用已注册的C函数)传递的参数,并将其传递给已注册的方法(代码段中的IDelegate),以便执行它并返回值

假设我从GameBoard类注册以下方法:
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;
    }
};