我刚刚在 Microsoft Visual C++ 2010 Express 中制作了一个解决方案,其中包含两个静态库项目(lib1 和 lib2)和一个应用程序项目(main),其中包含您描述的内容并且能够重现您的问题。这是我得到的完整构建输出:
1>----- 构建开始:项目:lib1,配置:调试 Win32 ------
1> MyClass.cpp
1> lib1.vcxproj -> c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\lib1.lib
2>------构建开始:项目:lib2,配置:调试Win32 ------
2> MyClass.cpp
2> 替换 Debug\MyClass.obj
2> lib2.vcxproj -> c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\lib2.lib
3>------构建开始:项目:主,配置:调试Win32 ------
3> 主.cpp
3>lib2.lib(MyClass.obj) : error LNK2019: unresolved external symbol "public: __thiscall LIB1::MyClass::MyClass(void)" (??0MyClass@LIB1@@QAE@XZ) 在函数“public: __thiscall LIB2::MyClass::MyClass(void)" (??0MyClass@LIB2@@QAE@XZ)
3>lib2.lib(MyClass.obj) : error LNK2019: unresolved external symbol "public: __thiscall LIB1::MyClass::~MyClass(void)" (??1MyClass@LIB1@@QAE@XZ) 在函数“public”中引用: __thiscall LIB2::MyClass::~MyClass(void)" (??1MyClass@LIB2@@QAE@XZ)
3>c:\users\samuel windwer\documents\visual studio 2010\Projects\linker_test\Debug\main.exe : 致命错误 LNK1120: 2 unresolved externals
========== 构建:2 成功,1 失败,0 最新,0 跳过 ==========
消息“Replaceing Debug\MyClass.obj”阐明了这个问题。此消息由 Microsoft 的库管理器 (LIB.EXE) 在构建 lib2.lib 时发出。为了理解此消息,重要的是要准确了解静态库文件 (.lib) 是什么,以及通过扩展了解 LIB.EXE 的作用。
第一件事是:在构建静态库时实际上没有链接任何代码。.lib 文件只是一个存档,其中包含一个或多个 .obj 文件。换句话说,.lib 文件的目的是提供一种方便的方式将 .obj 文件集合作为一个文件进行分发。LIB.EXE 所做的只是将项目的 .obj 文件打包成一个 .lib 文件。LIB.EXE 还具有对 .lib 文件执行其他操作的选项,例如列出所有包含的 .obj 文件并提取它们;有关详细信息,请参阅MSDN。
您的问题指出“lib1 中的 lib2 链接”。我假设这意味着您将 lib1.lib 作为“附加依赖项”放在 lib2 的项目设置中,如下图所示:

为了准确了解将 .lib 文件添加为像这样的静态库项目的“附加依赖项”的作用,在更改此设置后,我按照此答案中的过程查看运行 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 的对象这一事实是您问题的根源。正如MSDN 上的 LIB.EXE 文档中所述:
要将库成员替换为新对象,请指定包含要替换的成员对象的库以及新对象(或包含它的库)的文件名。当多个输入文件中存在同名对象时,LIB 会将 LIB 命令中指定的最后一个对象放入输出库中。
当 LIB.EXE 看到 MyClass.obj 的第二个实例时,消息“Replaceing Debug\MyClass.obj”会打印到控制台,因为它认为第二个 MyClass.obj 应该替换第一个。将其中一个 MyClass.cpp 文件重命名为 MyClass1.cpp 可以解决此问题,因为不再有两个名为 MyClass.obj 的目标文件,因此它们可以在同一个 .lib 文件中愉快地生活在一起。
您似乎已经为此想出了一些解决方法,但希望您现在了解您所看到的行为。