VC8到VC10 - LNK2005错误

时间:2011-04-08 10:42:53

标签: c++ visual-studio-2010 linker

我最近安装了Visual Studio 2010并使用CMake为我的项目生成解决方案文件。此过程之前在VS2005上运行良好。

我遇到的第一个问题是因为新的“移动构造函数”,所以我不得不从我的代码中删除一些隐式转换 - 公平,现在可以正常工作。

我目前的情况如下:我正在编译 DLL 1 ,它只依赖于某些系统库(Kernel32等)和CRT ,以及 DLL 2 ,链接到 DLL 1 ,以及一些第三方库。

我得到的错误是:

DLL1.lib(DLL1.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in objFromDLL2.obj

这似乎正是here所描述的问题。

但是,这个帖子中没有任何内容可以解决我的问题。

  • 我已确认DLL1和DLL2都是使用/ MD代码生成标志
  • 编译的
  • DLL2链接到squish,glew和devil - 我已经手动重新编译了所有这些以及它们依赖的所有库用于VC10,还有/ MD
  • 编辑根据this article(与我的问题类似),我删除了从std :: containers
  • 派生的任何类实例
  • 编辑我已经确认这不是第三方问题,因为我使用相同的库集成功编译了另一个项目,但是我仍然无法编译我的原始项目
  • 编辑 dllexport正在我的代码中的所有必需位置使用

我错过了什么?如果我需要提供更多信息,请告诉我,我会尽我所能编辑问题。

更新:已经有一段时间了,我仍然没有解决方案。我一直在用评论的回复来更新问题,我正在研究一个可行的不同代码库 - 我开始认为旧代码的向后兼容性终于开始枯竭,我应该只是继续前进。

more update:我发现了一个非常不受欢迎的链接器标志/ FORCE:MULTIPLE,它通过忽略符号的第一个定义而将错误转换为警告。这样做必然会产生不良副作用。对此标志的测试突出显示了LNK2001:未解析的std :: string :: npos,它隐藏在所有先前的LNK2005错误中。折磨永远不会结束。

3 个答案:

答案 0 :(得分:2)

我已成功使用/FORCE:MULTIPLE。使用混合包库时有时是不可避免的。只要链接器使用one&amp;相同的地址一致地解决参考,它的工作原理。其他定义被忽略。

答案 1 :(得分:0)

我倾向于认为你陈述的假设不正确。特别是,“DLL 1,它仅依赖于某些系统库(Kernel32等)”,如果用/ MD编译并引用std::string::~string,则不能正确。这显然会导致对CRT的依赖。

Aslo,如果DLL1不依赖于DLL2,那么世界上的链接器如何识别来自DLL2的文件?!您是否设法通过任何机会建立循环依赖?

在VS2008和VS2010之间,似乎已从CRT中删除std::string::~string。因此,它不再是您自己的代码的DLLimport。这可以解释行为上的差异。 DLL1和DLL2之间的循环依赖关系不会对std::string::~string产生影响,因为它们都会从CRT中获取它,而且显然不会成为循环的一部分。

答案 2 :(得分:0)

似乎问题是DLL1确实导出std::string(可能是隐式的,因为它在一个也被导出的类中使用),但是DLL1的头部没有声明。因此,当编译DLL2时,它不会被指出为导入。这没问题,因为它是一个模板:编译器只是实例化另一个副本。但随后链接器发生故障,因为DLL2确实应该导入std::string

解决方案:明确导出/导入std::string;您可能已经在DLL1标题中有_declspec( )的适当宏。