创建具有特定签名的c++静态包装器函数
Creating a C++ static wrapper function with specific signature
我在使用模板参数创建静态包装器函数时遇到了一些麻烦。我不想将函数直接传递给包装器函数,因为它需要一个特定的签名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>));
}
在第一种情况下,因为值不允许改变,我们知道如果它是外部链接的,它在技术上仍然是外部链接的。在第二种情况下,它作为一个引用被传递进来,这意味着它应该有相同的链接,不是吗?但这两种尝试都没有奏效。为什么?有可能绕过这个吗?我如何能干净地自动生成调用另一个函数的函数?
const
限定符意味着您不允许更改某些内容,而不是说它是编译时常量。_a
的初始值是在函数调用时确定的,对于* const &a
,如果引用的对象不是const
,则该值甚至可以在运行时通过某些外部手段(如另一个线程)更改。
要使完全模板化的包装器工作,您需要为编译器提供足够的信息,以便为每个可能的模板参数编译函数,并提供在这些函数之间切换的逻辑。模板系统生成并组织相关的函数,但它不是一个动态调度程序。
如果可以将函数指针添加到lua_State
对象并消除模板形参,那将是一个解决方案。
如果将函数指针作为doCaller
的模板参数,您的解决方案将有效,但这会破坏其目的。
与其使用非类型函数模板方法来绑定想要在包装器函数内部调用的第二个函数,不如使用struct
和静态luaCaller
方法。这应该允许您维护将luaCaller
传递给lua_pushcfunction
所需的函数签名。
例如,你可以有一个像这样的结构体:
template<void (*f) void>
struct wrapper
{
static int luaCaller(lua_State * _luaState)
{
f();
return 0;
}
};
template<typename Functor>
void doCaller(lua_State * _luaState, Functor wrapper)
{
Functor::luaCaller(_luaState);
}
然后像这样调用它:
doCaller(&luaState, wrapper<my_func>());
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 私有类型的静态常量成员
- 使用gcc从静态链接的文件中查找可选符号
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 如何在C++中使用非静态成员函数作为回调函数
- 将静态库链接到不带-fPIC的共享库中
- 静态结构和一个定义规则
- 为什么虚函数不能是静态的和全局的?
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身