.lib 中的 C++ 静态变量未初始化
我在 VS2010 中有静态库 (.lib) 并将其链接到我的测试项目.
I have static library (.lib) in VS2010 and am linking it to my test project.
该库有一个我使用以下宏创建的工厂:
The lib has a factory that I create using the below MACRO:
#define REGISTER_FACTORY(mType, my_class)
class Factory##my_class : public CAbstractFactory
{
public:
Factory##my_class() : CAbstractFactory(mType){}
CBaseClass *Create()
{ return new my_class(); }
};
static Factory##my_class StaticFactory##my_class;
应该发生的是,在 CAbstractFactory 中,新工厂通过 mtype
注册.但是当我检查工厂时,工厂不存在.
What is supposed to happen is that in the CAbstractFactory the new factory gets registered by mtype
. But when I check the factory the factory does not exist.
当我使用 DLL 而不是 .lib 时它工作正常.我的猜测是链接器不包含静态变量,因为它没有被引用,或者静态变量甚至没有包含在库中.
It works fine when I use a DLL instead of a .lib. My guess is that the linker does not include the static variable as it is not referenced or the static variable was not even included in the library.
如何强制链接器将静态库中的所有对象包含在我的 .exe 中.
How can I force the linker to include all objects from the static library in my .exe.
我像这样使用宏:
// Register factory that can create CMyObject with ID=100
REGISTER_FACTORY(100, CMyObject);
class CMyObject
{
};
CAbstractFactory 看起来像这样:
The CAbstractFactory looks like this:
class CAbstractFactory {
CAbstractFactory(int id) {
CFactory::instance().add(id, this);
}
}
然后是代码中的其他地方,我使用的主要 .exe:
Then some where else in the code, my main .exe I use:
CBaseClass *pObject = CFactory::instance().Create(100);
这会给我一个新的CMyObject
.这个想法是我有许多不同种类的对象,我有一个包含指定我需要的对象种类的 id 的数据库.100
只是一个例子.
This will then give my a new CMyObject
. The idea is that I have many different kind object and I have a database containing the id specifying the kind of objects I need.
100
is just an example.
确实,我没有直接从 .lib 中引用任何内容,但我希望能够使用我的工厂创建对象
So indeed, I do not reference anything from the .lib directly but I want to be able to create the objects using my factory
CFactory 类是一个简单的类,它保存所有 CAbstractFactory 类的寄存器(在映射中)并将 create 方法委托给正确的工厂.
The CFactory class is a simple class that keeps a register (in a map) of all the CAbstractFactory classes and delegates the create method to the correct factory.
CFactory &CFactory::Instance()
{
static CFactory instance;
return instance;
}
主要问题在于我没有从 .lib 中引用任何内容,因为它都是通过 CFactory 完成的.如果我将其设置为 DLL 并确保我添加了对这个 DLL 的一些引用以确保它被加载,它就可以工作.但是对于 .lib,我什至添加了一个虚拟函数,以确保我至少有一个不包含其余代码的引用.
The main problem lies in the fact that I do not reference anything from the .lib as it is all done through the CFactory. It works if I make it a DLL and make sure I add some reference to this DLL to make sure it is loaded. But for a .lib, I even added a dummy function to make sure I have at least one reference that doesn't include the rest of the code.
推荐答案
我遇到了类似的问题,通过将 lib 项目设置为主应用项目的依赖项,然后设置链接库依赖项"和使用库"来解决主要项目的依赖项输入'为是.
I had a similar problem and solved it by setting the lib project as a dependency of the main app project and then setting 'Link Library Dependencies' and 'Use Library Dependency Inputs' to Yes for the main project.
更新:
最近我发现 Visual Studio 2015 现在支持 /WHOLEARCHIVE
链接器标志.我无法通过链接器选项找到它,但您可以将其添加为附加命令行选项.它的工作原理类似于 GCC 标志 -whole-archive
并将其添加到目标链接器标志(而不是静态库标志).
Recently I discovered that Visual Studio 2015 now supports a /WHOLEARCHIVE
linker flag. I can't find it through the linker options, but you can add it as an additional command line option. It works similar to the GCC flag -whole-archive
and you add it to your target linker flags (not to the static lib flags).
例如,指定 /WHOLEARCHIVE:lib_name
作为附加链接器命令行选项,它将包含该库中的所有符号.您也可以执行多个库.
For example, specify /WHOLEARCHIVE:lib_name
as an additional linker command line option and it will include all symbols from that lib. You can do this more than one lib as well.
如果您使用此 /WHOLEARCHIVE:lib_name
,则不再需要将链接库依赖项"和使用库依赖项输入"设置为是".这非常适合通过 CMAKE 生成的解决方案.在此处查看相关答案:https://stackoverflow.com/a/42083877/1151329
If you use this /WHOLEARCHIVE:lib_name
you no longer need the 'Link Library Dependencies' and 'Use Library Dependency Inputs' set to Yes. This is perfect for solutions generated through CMAKE. See a related answer here: https://stackoverflow.com/a/42083877/1151329
相关文章