考虑下面的一对函数:
double MYAPI foo(double x) {
return x;
}
Register register_foo_([] {
return reg(&foo, "foo", ...); // function name repeated used
});
register_foo_
是一个全局变量,在dllmain
之前初始化,其构造函数采用一个lambda,它反复引用字面上方的函数名称。如果注册代码可以在上面的函数内移动以减少出错的可能性,那将是很好的。我试过了:
double MYAPI foo(double x) {
static Register register_foo_([] {
return reg(&foo, "foo", ...); // static local does not initialize before dllmain
});
return x;
}
如果以上代码有效,那么我可以轻松将其转换为使用__FUNCNAME__
的宏。有没有办法强制在dllmain之前初始化静态局部变量register_foo_
答案 0 :(得分:3)
函数(方法)本地的静态变量在首次使用它们所在的函数时初始化。(它们在程序加载时初始化为零,然后在首次输入函数时通过代码“正确”初始化。 )见answers to this question。因此,您建议将该代码移动到函数中会改变初始化的语义,并且它将无法工作。
你的原始代码是有效的,所以你显然想要的是将代码移到函数内部,以便它在某种程度上紧密地联系在一起 - 或者代码的读者的头脑 - 这样你就可以看到你的字符串了常量名称和功能名称是对的。也许这样你就可以确保注册完成了。因此你想要的是干涸。
通过使用扩展到注册调用和函数头的预处理器宏来实现这一目标的传统(也是唯一)方法。
您建议自己使用宏 - 现在展开宏,这样它不仅可以生成注册函数,还可以 函数头。
答案 1 :(得分:3)
这会在main()
之前运行一个函数,不确定它是否适用于dllmain()
:
#include <iostream>
int func_before_main()
{
std::cout << "func_before_main()" << '\n';
// do before main stuff
return 0;
}
const int dummy = func_before_main();
int main()
{
std::cout << "main()" << '\n';
}
<强>输出:强>
func_before_main()
main()
答案 2 :(得分:1)
我想你想要实现类似于:
的语法DEFINE_FUNC(void, foo, (double x)) {
return x;
}
...并自动生成样板。如果你在声明的帮助下将Register
带到函数之上,这实际上非常简单:
#define DEFINE_FUNC(Ret, name, args) \
Ret name args; \
Register register_##name##_([] { \
return reg(&name, #name, ...); \
}); \
Ret name args
答案 3 :(得分:0)
不,没有。那是你的答案。