我有一个静态调用初始化例程的函数。这是插件系统所需要的,其中插件要么是动态加载的(工作正常),要么也可以是静态链接的。由于主应用程序不知道静态插件,它必须注册自己,以便主应用程序知道它(就像它是动态加载的插件一样)。
现在的问题是初始化从未被调用。但是,当我添加一个虚拟函数并从主应用程序调用它时,初始化程序突然被调用。所以这在我看来好像初始化是从 gcc 中“优化”的。
static bool registerPlugins(void)
{
std::cout << "Registering CSV static plugin ... " << std::endl;
PluginManager::registerStaticPlugin(&PluginInfo);
return true;
}
static bool gCSVRegistered = registerPlugins();
Run Code Online (Sandbox Code Playgroud)
永远不会打印文本“正在注册...”,但添加了虚拟功能
void helper(void)
{
std::cout << "Registered: " << gCSVRegistered << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
...并从主应用程序中调用它,然后打印所有期望的文本。
那么我怎样才能强制静态初始化器不被扔掉???
我正在将 Mingw32 与 gcc 4.9.2 一起使用(仅供记录:))。
重要更新:相关代码在静态库中。在这种情况下,它不会被触发,只有当模块直接链接到主应用程序时才会调用初始化器。
main.cpp:
#include <iostream>
const char *gData = NULL;
int main()
{
if(gData)
std::cout << "Registration: " << gData << std::endl;
else
std::cout << "Registration: NULL" << std::endl;
return 0;
}
void registered(const char *pData)
{
gData = pData;
}
Run Code Online (Sandbox Code Playgroud)
static1.cpp
void registered(const char *pData);
static bool registration(void)
{
registered("Static initializer 1");
return true;
}
static bool reg = registration();
Run Code Online (Sandbox Code Playgroud)
static2.cpp
void registered(const char *pData);
static bool registration(void)
{
registered("Static initializer 2");
return true;
}
static bool reg = registration();
Run Code Online (Sandbox Code Playgroud)
static library: lib_main.cpp
void registered(const char *pData);
static bool registration(void)
{
registered("Static initializer library");
return true;
}
static bool reg = registration();
Run Code Online (Sandbox Code Playgroud)
所以因为对这个问题的评论最终引导我走向了正确的方向。问题在于该函数位于静态库中,如果主应用程序中未使用该代码,则不会调用该代码,因为链接器甚至不会将代码添加到可执行文件中。
为了更详细的描述,我发现了这个问题: Static初始化和销毁静态库的全局变量不会发生在g ++中
为了强制调用代码,我必须将注册移动到肯定需要的模块中(从而被链接到),或者使用链接器选项-Wl,--whole-archive。