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

时间:2014-05-22 04:11:25

标签: c++ visual-studio-2010 dll static-libraries static-members

我在VS2010中有静态库(.lib),并将其链接到我的测试项目。

lib有一个我用以下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注册。但是当我检查工厂时工厂不存在。

当我使用DLL而不是.lib时,它工作正常。我的猜测是链接器不包含静态变量,因为它没有被引用,或者静态变量甚至没有包含在库中。

如何强制链接器在我的.exe中包含静态库中的所有对象。

我像这样使用宏:

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

class CMyObject
{
};

CAbstractFactory如下所示:

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

然后在代码中的其他地方,我使用的主要.exe:

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

这将为我提供一个新的CMyObject。我的想法是,我有许多不同类型的对象,我有一个数据库,其中包含指定我需要的对象类型的id。 100只是一个例子。

事实上,我没有直接引用.lib中的任何内容,但我希望能够使用我的工厂创建对象

CFactory类是一个简单的类,它保存所有CAbstractFactory类的寄存器(在地图中),并将create方法委托给正确的工厂。

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

主要问题在于我没有引用.lib中的任何内容,因为它都是通过CFactory完成的。它是有效的,如果我使它成为一个DLL,并确保我添加一些引用到这个DLL,以确保它被加载。但对于.lib,我甚至添加了一个虚函数,以确保我至少有一个不包含其余代码的引用。

2 个答案:

答案 0 :(得分:7)

我有一个类似的问题,并通过将lib项目设置为主应用程序项目的依赖项,然后设置“链接库依赖项”来解决它。和'使用库依赖项输入'对于主项目来说是的。


更新

最近我发现Visual Studio 2015现在支持/WHOLEARCHIVE链接器标志。我无法通过链接器选项找到它,但您可以将其添加为附加命令行选项。它类似于GCC标志-whole-archive,并将其添加到目标链接器标志(而不是静态lib标志)。

例如,将/WHOLEARCHIVE:lib_name指定为附加链接器命令行选项,它将包含该lib中的所有符号。您也可以使用多个lib。

如果您使用此/WHOLEARCHIVE:lib_name,则不再需要'链接库依赖关系'和'使用库依赖项输入'设为是。这非常适合通过CMAKE生成的解决方案。请在此处查看相关答案:https://stackoverflow.com/a/42083877/1151329

答案 1 :(得分:0)

static定义了一个具有内部链接的对象 - >如果它没有在同一个翻译单元中使用内部,则可以对其进行优化。从实例中删除static,以使对象具有外部链接 - Factory##my_class StaticFactory##my_class;