如何在c++中强制包含静态库中的静态对象(msvc11)

How to force include static objects from a static library in C++ (MSVC 11)

本文关键字:静态 对象 msvc11 包含 c++      更新时间:2023-10-16

我试图在c++文件中初始化一个静态对象,该文件试图在其构造函数中自动注册一个类到工厂(如任何标准的自动注册问题)。问题是,它被编译成一个静态库,当链接到一个可执行文件时,它被优化掉了。应该有一个非常简单的解决方案,但令人惊讶的是,看起来并没有那么简单。

这是我的类:

Factory.h(静态库项目的一部分)

class DummyClass : public BaseFactoryClass
{
    int mDummyInt;
public:
    DummyClass()
    {
        std::cout << "Pretending to register myself to the factory heren";
    }
};

在某些cpp中,我们说Circle.cpp(仍然是静态库项目的一部分)

static DummyClass dum;

main.cpp(可执行文件的一部分)

//some code accessing the BaseFactoryClass of the Registered derived classes. 

现在,因为静态对象不是在可执行项目中"直接"使用的,所以它从链接库中被跳过。

我想让它在MS VC11 (Visual Studio 2012)(和GCC 4.8)中工作。*,但这是以后的事)。看看其他问题,到目前为止,我尝试了各种各样的方法,但似乎都不起作用:

  1. 看起来/WHOLEARCHIVE链接选项只被Visual支持Studio 2015(我们使用VS 2012)
  2. 指定/OPT:NOREF应该已经工作了(我尝试了几个与其他标志的组合,如/OPT:NOICF),但它不适合任何人。
  3. 我在头文件中尝试了#pragma comment (linkker, "/include:symbolName"),但这给了一个关于符号无法识别的链接器错误。(这也不能在GCC中工作,但可能在那里-whole-archive可以工作)。

在Visual Studio链接器设置中有一个标志,允许单独链接所有目标文件,而不是静态库,但我不想走那条路。此外,最好我只是想在每个单独的类的源代码(.cpp)中写一些东西,我想自动注册,所有的锅炉板代码和宏都在一个中央头,如BaseFactory.h等。有什么方法可以做到这一点(即使在c++ 11中,有一个符号将被初始化的保证)?

在MSVC中,你有一个可以用于此目的的链接器pragma:

#pragma comment (linker, "/export:_dum")

这样,每当链接器运行时,它将在可执行文件或DLL中强制链接_dum

但是,一个更好的方法是考虑使用DLL而不是静态库。这样就完全避免了这个问题,因为每次加载DLL时都会初始化静态变量。