【发布时间】: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;
main.cpp(可执行文件的一部分)
//some code accessing the BaseFactoryClass of the Registered derived classes.
现在,由于静态对象没有在可执行项目中“直接”使用,因此已从链接库中跳过。
我想让它在 MS VC11 (Visual Studio 2012)(和 GCC 4.8.*,但那是以后的)中工作。查看其他问题,到目前为止,我尝试了各种方法,但似乎不起作用:
- 看起来 /WHOLEARCHIVE 链接器选项仅受 Visual 支持 Studio 2015(我们使用的是 VS 2012)
- 指定 /OPT:NOREF 应该可以工作(我尝试了几种将其与 /OPT:NOICF 等其他标志结合使用),但对任何人都不起作用。
- 我在头文件中尝试了#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