我在使用模板参数创建静态包装函数时遇到了一些麻烦。我不想将函数直接传递给包装函数,因为它需要特定的签名int (lua_State *)
,以便可以将其传递给以下函数:
lua_pushcfunction(L, function);
(没错,我要的是自动生成的 lua 包装器。)
我的第一个想法是创建一个带有函数指针作为非类型模板参数的模板函数。
template <void(* f)(void)>
int luaCaller(lua_State * _luaState)
{
f();
return 0;
}
到目前为止,这看起来相当不错。该函数具有正确的签名,并调用我通过模板参数传入的函数。
&(luaCaller<myFunc>)
当我尝试将其包装在另一个函数中时,我的问题就出现了。非类型模板参数必须外部链接,因此以下失败:
void pushFunction(lua_State * _luaState, void(* _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
这是有道理的,因为函数的地址需要在编译时知道。您不能只输入任何指针并期望编译器知道要创建哪些类。不幸的是,如果我添加一个在编译时已知的函数指针,它仍然会失败。函数指针的值被复制到 _a 中,因此 _a 在编译时在技术上仍然未知。因此,我希望以下工作:
void pushFunction(lua_State * _luaState, void(* const _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
或者可能
void pushFunction(lua_State * _luaState, void(* & _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
在第一种情况下,因为不允许更改值,所以我们知道如果它是外部链接的,它在技术上仍然是外部链接的。在第二种情况下,它作为参考传递,这意味着它应该具有相同的链接,不是吗?但这些尝试都没有奏效。为什么?是否有可能以某种方式规避这一点?如何干净地自动生成调用另一个函数的函数?