【问题标题】:How to force include static objects from a static library in C++ (MSVC 11)如何在 C++ (MSVC 11) 中强制包含静态库中的静态对象
【发布时间】:2016-09-05 19:43:13
【问题描述】:

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

这是我的课:

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

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

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

static DummyClass dum;

ma​​in.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 (linker, "/include:symbolName"),但是这给出了一个关于符号无法识别的链接器错误。 (而且这在 GCC 中也行不通,但可能 --whole-archive 在那里工作)。

Visual Studio 链接器设置中有一个标志允许单独链接所有对象文件而不是静态库,但我不想走那条路。另外,最好我只想在我想自动注册的每个单独类的源代码(.cpp)中写一些东西,所有的样板代码和宏都在像 BaseFactory.h 这样的中心头文件中。有没有如何做到这一点(即使在 C++ 11 中也可以保证符号会被初始化)?希望让任何新开发者都能尽可能轻松地注册新类。

【问题讨论】:

  • 为什么你的dum 对象是静态的?我想删除 static 关键字将解决您的问题。通过使您的对象静态,只有 Circle.cpp 可以访问此变量。
  • 嗨,我已经试过了。由于在可执行项目中没有直接引用它,因此删除了静态和全局变量。我可以创建一个访问器函数并在导致其创建的 main.cop 文件中调用它,但我真的不想这样做,因为那里不需要它(只需要它注册的类)。
  • @JesperJuhl:我不这么认为。对我来说,静态对象甚至没有被创建,因为它位于静态库中,并且没有在可执行项目中直接引用。
  • @JesperJuhl:不,这是一个排序问题,但只有在创建所涉及的两个对象时才会发生。这是一个对象,而不是两个,它甚至都没有被创建。

标签: c++ visual-studio-2012 static linker static-linking


【解决方案1】:

在 MSVC 中,您有一个可用于此目的的链接器编译指示:

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

这样,无论何时运行链接器,它都会在您的可执行文件或 DLL 中强制链接 _dum

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

【讨论】:

    猜你喜欢
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多