类具有相同的文件名在不同库继承问题
当从驻留在不同的lib中的链接器产生一个解析的外部符号错误相同的文件名一个类继承。想想这个继承:LIB2 :: MyClass:public LIB1 :: MyClass。类具有相同的文件名在不同库继承问题
静态库 “LIB1”:
MyClass.h:
namespace LIB1
{
class MyClass
{
public:
MyClass();
~MyClass();
};
}
静态库 “LIB2”:
MyClass.h:
#include "..\MyClass.h" // Header of MyClass from lib1 somewhere else than this header file
namespace LIB2
{
class MyClass : public LIB1::MyClass
{
public:
MyClass();
~MyClass();
};
}
假设两者。 cpp文件存在。在LIB1
LIB2链接
一些可执行文件后,试图LIB2链接和使用派生MyClass的,说
#include "\lib2\MyClass.h"
int main()
{
LIB2::MyClass c;
}
链接失败,
错误LNK2001:无法解析的外部符号“公用: __thiscall LIB1 :: MyClass ::〜MyClass(void)
(与ctor相同)
当我简单地将其中一个MyClass.cpp的文件名更改为MyClass1.cpp时,一切都很好。
不是搜索LIB1的定义:在lib1.lib链接MyClass的试图找到他们MyClass.obj(从LIB2)我怀疑。
这种行为只是感觉太奇怪,是故意。我错过了什么?
此外,当在VS2005/2010中设置一个解决方案,包括库和可执行文件,并让VS通过Project Properties-> Common Properties-> Framework和References来设置所有lib依赖关系(而不是提供路径到库中的链接器设置)链接成功。
我只是做了在Microsoft Visual C++ 2010速成包含两个静态库项目(LIB1和LIB2),并与你所描述的内容的应用程序项目(主)的解决方案,并能够重现你的问题。下面是完整的构建输出我得到:
1>------ Build started: Project: lib1, Configuration: Debug Win32 ------ 1> MyClass.cpp 1> lib1.vcxproj -> c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\lib1.lib 2>------ Build started: Project: lib2, Configuration: Debug Win32 ------ 2> MyClass.cpp 2> Replacing Debug\MyClass.obj 2> lib2.vcxproj -> c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\lib2.lib 3>------ Build started: Project: main, Configuration: Debug Win32 ------ 3> main.cpp 3>lib2.lib(MyClass.obj) : error LNK2019: unresolved external symbol "public: __thiscall LIB1::MyClass::MyClass(void)" ([email protected]@@[email protected]) referenced in function "public: __thiscall LIB2::MyClass::MyClass(void)" ([email protected]@@[email protected]) 3>lib2.lib(MyClass.obj) : error LNK2019: unresolved external symbol "public: __thiscall LIB1::MyClass::~MyClass(void)" ([email protected]@@[email protected]) referenced in function "public: __thiscall LIB2::MyClass::~MyClass(void)" ([email protected]@@[email protected]) 3>c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\main.exe : fatal error LNK1120: 2 unresolved externals ========== Build: 2 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
消息“更换调试\ MyClass.obj”揭示了这个问题的一些情况。此消息是在构建lib2.lib时由Microsoft的库管理器(LIB.EXE)发出的。为了理解这个消息,了解一个静态库文件(.lib)是什么以及通过扩展来准确理解LIB.EXE的作用是非常重要的。
第一件事的第一:建立一个静态库时没有代码实际上是联系在一起的。 .lib文件只是一个包含一个或多个.obj文件的归档文件。换句话说,.lib文件的目的是提供一种方便的方式将一组.obj文件作为一个文件分发。 LIB.EXE所做的就是将项目的.obj文件打包到.lib文件中。 LIB.EXE也可以选择使用.lib文件做其他事情,例如列出所有包含的.obj文件并提取它们;有关更多信息,请参阅MSDN。
您的问题指出“lib2中的lib2链接”。我假设这意味着,你把lib1.lib在LIB2的项目设置的“附加依赖”,如在此截图:
为了准确了解加入的.lib文件这样的静态库项目的“附加依赖项”会在更改此设置后执行this answer中的过程以查看运行LIB.EXE以构建lib2.lib时使用的命令行。这里是:
lib.exe "/OUT:c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\lib2.lib" lib1.lib /LIBPATH:..\Debug Debug\MyClass.obj
此命令生成lib2.lib在命名一个新的静态库文件包含所有lib1.lib的.OBJ文件,以及MyClass.obj。 lib1.lib还包含名为MyClass.obj的对象这一事实是问题的根源。正如LIB.EXE's documentation on MSDN指出:
要使用一个新的对象替换库成员,指定包含要被替换的构件对象并为新的对象(或包含它的库)的文件名的库。当多个输入文件中存在具有相同名称的对象时,LIB会将LIB命令中指定的最后一个对象放入输出库中。
“更换调试\ MyClass.obj”该消息被输出到控制台时LIB.EXE看到,因为它认为的是,第二MyClass.obj应该更换的第一个MyClass.obj的第二个实例。将MyClass.cpp文件中的一个重命名为MyClass1.cpp可以修复此问题,因为不再有两个名为MyClass.obj的对象文件,因此它们都可以在同一个.lib文件中一起愉快地生活。
看来您已经为此提出了一些解决方法,但希望您现在了解您所看到的行为。
感谢您关注链接。在禁用LIB.exe的/ NOLOGO选项后,我可以看到打包到lib中的对象文件被它们的相对路径引用。对于MyClass示例,命令行输出如下所示:** Debug/MyClass.obj替换为Debug/MyClass.obj **因此,解决方案是将lib1的目标文件保存到不同的位置lib2的。 (DebugLib1/*。obj,DebugLib2/*。obj)然后,lib1的对象可以链接到lib2中,而不会在具有相同文件名的情况下冲突对象名称。 – 2012-02-06 13:08:42
非常欢迎。我很高兴我的回答帮助您找到了一个更理想的解决方案来解决您的问题。 – chess007 2012-02-07 00:46:53
编辑:而不是在lib1.lib搜索LIB1:MyClass的定义链接器试图找到它们在MyClass.obj(从lib2)我怀疑...对不起,忘了那,这没有任何意义 – 2012-02-03 15:12:17