简体   繁体   English

.lib 中的 C++ 静态变量未初始化

[英]C++ static variable in .lib does not initialize

I have static library (.lib) in VS2010 and am linking it to my test project.我在 VS2010 中有静态库 (.lib) 并将其链接到我的测试项目。

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;

What is supposed to happen is that in the CAbstractFactory the new factory gets registered by mtype .应该发生的是,在 CAbstractFactory 中,新工厂由mtype注册。 But when I check the factory the factory does not exist.但是当我检查工厂时,工厂并不存在。

It works fine when I use a DLL instead of a .lib.当我使用 DLL 而不是 .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.我的猜测是链接器不包含静态变量,因为它没有被引用,或者静态变量甚至没有包含在库中。

How can I force the linker to include all objects from the static library in my .exe.如何强制链接器将静态库中的所有对象包含在我的 .exe 中。

I use the macro like this:我像这样使用宏:

// Register factory that can create CMyObject with ID=100
REGISTER_FACTORY(100, CMyObject);

class CMyObject
{
};

The CAbstractFactory looks like this: CAbstractFactory 看起来像这样:

class CAbstractFactory {
    CAbstractFactory(int id) {
        CFactory::instance().add(id, this);
    }
}

Then some where else in the code, my main .exe I use:然后是代码中的其他地方,我使用的主要 .exe:

CBaseClass *pObject = CFactory::instance().Create(100);

This will then give my a new CMyObject .这将给我一个新的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.这个想法是我有许多不同种类的对象,我有一个包含指定我需要的对象种类的 id 的数据库。 100 is just an example. 100只是一个例子。

So indeed, I do not reference anything from the .lib directly but I want to be able to create the objects using my factory所以确实,我没有直接从 .lib 引用任何东西,但我希望能够使用我的工厂创建对象

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 类是一个简单的类,它保存所有 CAbstractFactory 类的寄存器(在映射中)并将 create 方法委托给正确的工厂。

CFactory &CFactory::Instance()
{
    static CFactory instance;
    return instance;
}

The main problem lies in the fact that I do not reference anything from the .lib as it is all done through the CFactory.主要问题在于我没有从 .lib 中引用任何内容,因为它都是通过 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.如果我将它设置为 DLL 并确保我添加了对这个 DLL 的一些引用以确保它被加载,它就可以工作。 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.我遇到了类似的问题,并通过将 lib 项目设置为主应用程序项目的依赖项,然后将主项目的“链接库依赖项”和“使用库依赖项输入”设置为“是”来解决它。


Update:更新:

Recently I discovered that Visual Studio 2015 now supports a /WHOLEARCHIVE linker flag.最近我发现 Visual Studio 2015 现在支持/WHOLEARCHIVE链接器标志。 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).它的工作方式类似于 GCC 标志-whole-archive并将其添加到目标链接器标志(而不是静态库标志)。

For example, specify /WHOLEARCHIVE:lib_name as an additional linker command line option and it will include all symbols from that lib.例如,指定/WHOLEARCHIVE:lib_name作为附加的链接器命令行选项,它将包含该库中的所有符号。 You can do this more than one lib as well.您也可以执行多个库。

If you use this /WHOLEARCHIVE:lib_name you no longer need the 'Link Library Dependencies' and 'Use Library Dependency Inputs' set to Yes.如果使用此/WHOLEARCHIVE:lib_name ,则不再需要将“链接库依赖项”和“使用库依赖项输入”设置为是。 This is perfect for solutions generated through CMAKE.这非常适合通过 CMAKE 生成的解决方案。 See a related answer here: https://stackoverflow.com/a/42083877/1151329在此处查看相关答案: https : //stackoverflow.com/a/42083877/1151329

static defines an object with internal linkage --> if it's not used internally in the same translation unit, it can be optimized out. static定义了一个具有内部链接的对象 --> 如果它不在同一翻译单元内部使用,则可以对其进行优化。 Remove the static from your instantiation for the object to have external linkage - Factory##my_class StaticFactory##my_class;从您的实例化中删除static对象以获得外部链接 - Factory##my_class StaticFactory##my_class;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM