【问题标题】:Visual studio cross linking DLL built from different VC compiler从不同的 VC 编译器构建的 Visual Studio 交叉链接 DLL
【发布时间】:2017-06-11 10:19:27
【问题描述】:

正在将项目与使用不同版本的兼容工具集构建的库链接。当我在 VS2015/2013 之间尝试此操作时,C++ 链接器抱怨 MSVC_version 不同。

error LNK2038: mismatch detected for '_MSC_VER': value '1900' doesn't match value '1800'
  • 我做错了什么还是这是预期的行为?

  • 1234563 +03 抱怨旧编译器只有 32 位。但似乎仍然可以使用智能编译器/链接器选项来允许这样做?

最后,我在尝试使用一个使用 C++11 特性的开源库时偶然发现了这一点。但是我的很多项目现有代码都在 2013 年。无论如何在不完全升级我的项目的情况下使用库功能?我确定我缺少一些东西,因为很多库应该独立工作,例如使用旧驱动程序安装在旧 Windows 机器等的 api 库,我缺少什么?

-谢谢。

【问题讨论】:

    标签: visual-studio c++11 dll visual-studio-2013 visual-studio-2015


    【解决方案1】:

    编译器版本之间有许多微妙的变化可能导致它们不兼容。

    • 基类的顺序。
    • 具有不同访问说明符的成员变量的顺序。
    • 结构填充。
    • std::vector等标准库类的实现。
    • 非内联原语的内部实现辅助函数,例如在 32 位系统上将 64 位整数左移。
    • 用于 RTTI、stack probesGSCFG 等功能的内部实现帮助函数。
    • LTCG 对象文件的内部格式。

    任何这些都会导致由一个版本的编译器编译的目标文件与由不同版本的编译器编译的目标文件不兼容。其中一些不兼容会导致链接错误,但其他不兼容会导致可执行文件出现神秘的运行时错误。

    【讨论】:

      【解决方案2】:

      C/C++ 没有“通用 ABI”,但只要确保它们使用一致的调用,您通常可以在英特尔平台上获取 C 样式导出以链接到英特尔平台上的其他 C 样式导出习俗。如果他们使用相同的名称修饰方案,您可以让一些 C++ 代码与来自不同编译器的其他 C++ 代码链接——英特尔努力使他们的编译器链接与 Visual C++ 兼容。

      当然,这一切都与内联代码有关,特别是标准 C++ 库不能保证匹配。出现链接错误是因为 Visual C++ 仅在同一版本(即更新 1 到更新 2)中维护编译器/标准库的兼容性,而不是在主要版本之间(VS 2013 到 VS 2015)。

      请注意,在 VS 2017 中,C/C++ 库实际上与 VS 2015 版本相同。

      【讨论】:

      • 谢谢。 ABI 是我一直在寻找的神奇词汇。关于操作系统如何实际设计和使用驱动程序的大量阅读。这直接回答了问题的第二部分。如果 C 编译器具有相同的名称修饰和 C 版本,交叉链接总是安全的吗?我想知道它是否会在运行时导致未知的内存/指针问题,因为没有标准 ABI
      • 如果他们使用相同的名称修饰和相同的调用约定是安全的。对于 cdeclstdcallfastcallvectorcall 的 Windows x86 代码。
      • 不一定安全。例如,va_listjmp_buf 的内部格式可以在编译器版本之间改变。
      • 很公平:安全 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多