Visual C++ 中多个项目之间的链接错误

11

我有一个包含多个项目的解决方案。我有一个名为“main”的项目,它充当菜单,从那里用户可以访问任何其他项目。在这个主项目中,每个被调用的函数都会出现连接器错误。如何避免这些连接器错误?我已经在“项目依赖项...”对话框中设置了项目依赖关系。

谢谢

编辑-- 我按建议添加了输出文件夹到链接器的附加目录中。然而,现在我得到了一百万个以下错误:

3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __thiscall std::basic_ios >::setstate(int,bool)" (?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __thiscall std::ios_base::width(int)" (?width@ios_base@std@@QAEHH@Z) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __thiscall std::basic_streambuf >::sputn(char const *,int)" (?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHPBDH@Z) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: static bool __cdecl std::char_traits::eq_int_type(int const &,int const &)" (?eq_int_type@?$char_traits@D@std@@SA_NABH0@Z) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: static int __cdecl std::char_traits::eof(void)" (?eof@?$char_traits@D@std@@SAHXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __thiscall std::basic_streambuf >::sputc(char)" (?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_streambuf > * __thiscall std::basic_ios >::rdbuf(void)const " (?rdbuf@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_streambuf@DU?$char_traits@D@std@@@2@XZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: char __thiscall std::basic_ios >::fill(void)const " (?fill@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEDXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __thiscall std::ios_base::flags(void)const " (?flags@ios_base@std@@QBEHXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __thiscall std::ios_base::width(void)const " (?width@ios_base@std@@QBEHXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: static unsigned int __cdecl std::char_traits::length(char const *)" (?length@?$char_traits@D@std@@SAIPBD@Z) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_ostream > & __thiscall std::basic_ostream >::flush(void)" (?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_ostream > * __thiscall std::basic_ios >::tie(void)const " (?tie@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_ostream@DU?$char_traits@D@std@@@2@XZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: bool __thiscall std::ios_base::good(void)const " (?good@ios_base@std@@QBE_NXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __thiscall std::basic_ostream >::_Osfx(void)" (?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __thiscall std::basic_streambuf >::_Lock(void)" (?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __thiscall std::basic_streambuf >::_Unlock(void)" (?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in panels.lib(panel_main.obj)
3>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::locale::facet * __thiscall std::locale::facet::_Decref(void)" (?_Decref@facet@locale@std@@QAEPAV123@XZ) already defined in panels.lib(panel_main.obj)
3>libcpmtd.lib(ios.obj) : error LNK2005: "private: static void __cdecl std::ios_base::_Ios_base_dtor(class std::ios_base *)" (?_Ios_base_dtor@ios_base@std@@CAXPAV12@@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(ios.obj) : error LNK2005: "public: static void __cdecl std::ios_base::_Addstd(class std::ios_base *)" (?_Addstd@ios_base@std@@SAXPAV12@@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(locale0.obj) : error LNK2005: "void __cdecl _AtModuleExit(void (__cdecl*)(void))" (?_AtModuleExit@@YAXP6AXXZ@Z) already defined in msvcprtd.lib(locale0_implib.obj)
3>libcpmtd.lib(locale0.obj) : error LNK2005: __Fac_tidy already defined in msvcprtd.lib(locale0_implib.obj)
3>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static void __cdecl std::locale::facet::facet_Register(class std::locale::facet *)" (?facet_Register@facet@locale@std@@CAXPAV123@@Z) already defined in msvcprtd.lib(locale0_implib.obj)
3>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Getgloballocale(void)" (?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Init(void)" (?_Init@locale@std@@CAPAV_Locimp@12@XZ) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_ctor(class std::_Locinfo *,class std::basic_string,class std::allocator > const &)" (?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_dtor(class std::_Locinfo *)" (?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::_Lockit(int)" (??0_Lockit@std@@QAE@H@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
3>libcpmtd.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::~_Lockit(void)" (??1_Lockit@std@@QAE@XZ) already defined in msvcprtd.lib(MSVCP90D.dll)
9个回答

20

没有了解你的解决方案的所有细节很难回答,但我假设你的"其他"项目是设置为生成 .lib 文件,而主项目则链接所有这些 lib 文件。如果是这种情况,则导致你遇到错误的可能原因是各个项目链接不同版本的运行库。

根据微软文档,"传递给链接器的所有模块必须使用相同的运行时库编译器选项 (/MD、/MT 或 /LD) 进行编译。"

尝试更改所有项目以使用相同版本的运行时库。在 Visual Studio 2010 中,这在项目的属性 | 配置属性 | C/C++ | 代码生成 | 运行时库中设置。选择 多线程调试 DLL多线程调试(针对你的调试配置)。


谢谢,Dani!我遇到了这个问题,你的解决方案很好。我的静态库的运行时库设置为“多线程调试”,而链接到它的应用程序设置为“多线程调试DLL”。将运行时库设置更改为使所有内容匹配可以解决链接器错误。 - vocaro
这正是导致我失败的原因。非常感谢。 - Rinor

11

不了解您的解决方案的其他细节,很难说,但“Rebuild All”可能有帮助。当不同架构的混合对象文件存在时,有时会出现这种情况。

您可能还想考虑使用“引用”而不是“依赖项”。

编辑:

根据您发布的内容,似乎您与标准库的链接不一致。是否可能其中一个项目静态链接标准库,而其他项目动态链接标准库?(请参见项目属性->链接器)或者链接到发行版运行时,而其他项目链接到调试版本?(虽然最后一个应该是可能的,但有条件限制)


我认为引用只用于.NET项目。虽然OP没有明确说明这一点,但我猜他在使用非托管的C++编写。 - Andy
3
谢谢您提到不一致的链接(/MT与/MD)。我之前没有考虑到这一点,使得链接一致解决了我的LNK2005错误。 - Helge Klein

2

你的其他项目中的函数是否已导出?如果没有导出,那么主exe文件无法链接到任何东西,这将导致错误。请参阅使用__declspec(export)从DLL导出以获取更多信息。


1
你遇到的错误是'error LNK2005',这意味着你在链接的库(msvcprtd.lib)中的一个符号已经在另一个库(例如panels.lib)中被定义过了。如果你将panels.lib添加到“忽略特定库”字段中(在VS2008配置属性-->链接器-->输入-->忽略特定库),错误就会停止。

0

我曾经遇到过一个非常类似的问题,原因是我的某个库的选项“将wchar_t视为内置类型”的值与其他库不同。在新项目中,默认情况下此设置为false。将它们全部改为true可以解决问题。


0

确切地说,你的其中一个项目使用了与其他项目不同的“Runtime Library”进行编译。也许你添加了一个默认不同的新库。检查你的项目属性以确保它们在“Configuration Properties” -> “C/C++” -> “Code Generation” -> “Runtime Library”中具有相等的值。


这难道不正是三年前Dani van der Meer所说的吗? - Joe Schrag

0
在我的情况下,问题是因为我将函数原型、类定义、函数实现和类实现都放在了一个cpp文件中。只有当我将声明和原型移到单独的头文件中时,这些错误才消失了。真的很奇怪!

0

我猜测你遇到的链接错误是“未解决的符号”?

如果使用静态库(即.lib文件),您需要将库添加到链接器输入中,以便在链接时可以链接符号。如果不这样做,您将会得到一个未解决的符号:

  1. 右键单击项目,选择属性。
  2. 选择配置属性->链接器->输入
  3. 在附加依赖项下输入库名称(例如filename.lib)。

1
当您在Visual Studio中添加项目依赖项时,它会自动为您链接到该项目的输出(但不会将.lib添加到属性中)。 - Andy

0

在我的情况下,我有两种方法:

  1. 项目属性 -> C/C++ -> 代码生成 -> 运行库。将其更改为MT。

  2. 将缺少的库添加到:链接器 -> 输入 -> 附加依赖项。如果不起作用,请尝试添加完整路径而不是库名称。

例如:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64\libvcruntime.lib;

这对我有用。回答任何需要帮助的人的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接