我在VS2010中具有静态库(.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,我什至添加了一个虚拟函数,以确保至少有一个引用不包含其余代码。
我遇到了类似的问题,并通过将lib项目设置为主应用程序项目的依赖项,然后将主项目的“链接库依赖项”和“使用库依赖项输入”设置为“是”,解决了该问题。
更新:
最近,我发现Visual Studio 2015现在支持/WHOLEARCHIVE
链接器标志。我无法通过链接器选项找到它,但是您可以将其添加为其他命令行选项。它的工作方式与GCC标志类似-whole-archive
,您可以将其添加到目标链接器标志(而不是静态lib标志)中。
例如,将其指定/WHOLEARCHIVE:lib_name
为附加的链接器命令行选项,它将包括该库中的所有符号。您还可以执行多个lib操作。
如果使用此选项/WHOLEARCHIVE:lib_name
,则不再需要将“链接库依赖项”和“使用库依赖项输入”设置为“是”。这是通过CMAKE生成的解决方案的完美选择。在此处查看相关答案:https : //stackoverflow.com/a/42083877/1151329
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句