VC8 到 VC10 - LNK2005 错误

发布于 2024-10-31 04:39:51 字数 1733 浏览 1 评论 0原文

我最近安装了 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

这似乎正是所描述的问题 此处

但是,该线程中的任何内容都不能解决我的问题。

  • 我已经确认 DLL1 和 DLL2 都是使用 /MD 代码生成标志进行编译的,
  • DLL2 链接到 smish、glew 和 Devil — 我已经为 VC10 手动重新编译了所有这些以及它们依赖的任何库 ,也可使用 /MD
  • 编辑 根据这篇文章(与我的问题类似),我已经删除了从 std::container 派生的类的任何实例
  • 编辑我已经确认这不是第三个派对问题,因为我已经使用同一组库成功编译了另一个项目,但是我仍然无法编译我的原始项目
  • edit dllexport 正在我的代码中的所有必需位置使用

我缺少什么?如果我需要提供更多信息,请告诉我,我会尽力编辑问题。

更新:已经有一段时间了,我仍然没有解决方案。我一直在更新问题并回复评论,并且我目前正在开发一个确实有效的不同代码库 - 我开始认为旧代码的向后兼容性终于开始枯竭,我应该继续前行。

更多更新:我发现了一个可能非常不受欢迎的链接器标志 /FORCE:MULTIPLE,它通过忽略除第一个符号定义以外的所有符号,将错误转变为警告。这样做肯定会产生不良的副作用。对该标志的测试突出显示了 LNK2001: 未解析的 std::string::npos,该错误被隐藏在所有以前的 LNK2005 错误中。折磨永远不会结束。

I recently installed Visual Studio 2010 and used CMake to generate the solution files for my project. This process had previously worked fine on VS2005.

The first issue I encountered was because of the new "move constructors", so I had to remove some implicit conversions from my code — fair enough, that works now.

My current situation is as follows: I am compiling DLL 1, which is dependent only on some system libraries (Kernel32, etc) and the CRT, and DLL 2, which links to DLL 1, as well as some third party libraries.

The errors I get are along the lines of:

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

This appears to be exactly the problem described here.

However, nothing in this thread solves my problem.

  • I have confirmed that both DLL1 and DLL2 are compiled with the /MD Code Generation flag,
  • DLL2 links to squish, glew, and devil — I have manually recompiled all of these and any libraries they depend on for VC10, also with /MD
  • edit As per this article (which is similar to my problem), I have removed any instances of classes deriving from std:: containers
  • edit I have confirmed this is not a 3rd party issue, as I have compiled another project successfully using the same set of libraries, however I still cannot compile my original project
  • edit dllexport is being used in all required places in my code

What am I missing? Please let me know if I need to provide more information and I will edit the question as best I can.

update: It's been a while and I still have no solution. I've been updating the question with responses to comments, and I'm currently working on a different codebase which does work - I'm starting to think that the backwards compatibility for older code has finally started to dry up, and I should just move on.

more update: I've found what's probably a very undesirable linker flag, /FORCE:MULTIPLE, which turns the errors into warnings by ignoring all but the first definition of the symbols. There must be bad side-effects of doing this. A test of this flag highlighted an LNK2001: unresolved std::string::npos, which was buried in all the previous LNK2005 errors. The torment never ends.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

原来分手还会想你 2024-11-07 04:39:51

我已成功使用 /FORCE:MULTIPLE 。使用混合库时,有时这是不可避免的。只要链接器使用 one &相同的地址来一致地解析引用,它有效。其他定义将被忽略。

I have used /FORCE:MULTIPLE successfully. It is sometimes inevitable when using a mixed bag of libraries. As long as the linker uses the one & same address to consistently resolve the reference, it works. The other definitions are ignored.

浮萍、无处依 2024-11-07 04:39:51

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

另外,如果 DLL1 不依赖于 DLL2,链接器到底如何知道来自 DLL2 的文件?!您是否设法建立了循环依赖关系?

在 VS2008 和 VS2010 之间,似乎 std::string::~string 已从 CRT 中删除。因此,它不再是您自己代码的 DLL 导入。这可以解释行为上的差异。 DLL1 和 DLL2 之间的循环依赖对 std::string::~string 来说并不重要,因为两者都会从 CRT 获取它,而这显然不会成为循环的一部分。

I'm inclined to think that your stated assumptions are incorrect. In particular, "DLL 1, which is dependent only on some system libraries (Kernel32, etc)" can't be right if it's compiled with /MD and refers to std::string::~string. That would obviously cause a dependency on the CRT.

Aslo, if DLL1 doesn't depend on DLL2, how in the world is the linker aware of files from DLL2?! Have you managed to set up a cyclic dependency by any chance?

Between VS2008 and VS2010, it seems that std::string::~string was removed from the CRT. Therefore, it's no longer a DLLimport for your own code. That could explain the difference in behavior. A cyclic dependency between DLL1 and DLL2 wouldn't have mattered to std::string::~string since both would get it from the CRT, and that obviously wouldn't be part of the cycle.

玩心态 2024-11-07 04:39:51

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

解决方案:显式导出/导入std::string;您可能已经在 DLL1 标头中为 _declspec( ) 提供了适当的宏。

It seems that the problem is that DLL1 does export std::string (probably implicitly, because it's used in a class that's also exported), but the headers of DLL1 don't declare that. Therefore, when DLL2 is compiled, it's not noted as an import. This is no problem, because it's a template: the compiler just instantiates another copy. But then the linker stumbles, because DLL2 really should have imported std::string.

Solution: explicitly export/import std::string; you probably already have an appropriate macro for the _declspec( ) in your DLL1 header(s).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文