gpt4 book ai didi

c++ - 为什么旧编译器构建的某些库可以链接到现代代码,而其他库则不能?

转载 作者:行者123 更新时间:2023-12-04 07:56:35 25 4
gpt4 key购买 nike

我们有很多预构建的库(主要通过 CMake),使用 Visual Studio 2017 v141 构建。当我们尝试对使用 Visual STudio 2019 v142 的项目使用这些时,我们会看到如下错误:

Error C1047 The object or library file‘boost_chrono-vc141-mt-gd-x32-1_68.lib’ was created by a differentversion of the compiler than other objects...


另一方面,我们也使用来自 3rd-party 供应商的预编译 .libs,它们已经有十多年的历史了,当与我们的代码库链接时,这些库工作得很好。
是什么决定了图书馆是否需要重建,为什么有些古老的图书馆仍然可以使用而其他只有一个版本的图书馆不能使用?

最佳答案

我将尝试回答一些不可或缺的部分,但请注意,此答案可能不完整。有了来自同行的更多信息,我们也许能够构建一个完整的答案!
最简单的链接是指向 C图书馆。由于没有类和重载函数名称的概念,编译器创建者能够通过函数的纯名称创建函数的入口点。这似乎几乎是准标准化的,因为我自己还没有遇到过纯粹的 C库至少不能链接到我的项目。您可以在 C++ 中选择此行为通过在函数声明前面加上 extern "C" 来编写代码. (这也使得从 C# 代码链接到库变得容易)Here is a detailed explanation about extern "C" .但据我所知,这种行为不是标准化的;就是这么简单——看起来——只有一个合理的解决方案。
走进C++我们开始遇到重复的函数、变量和结构名称。让我们在这里只讨论重载函数。为此,编译器创建者必须在 void a(); void a(int x); void a(char x); ... 之间提出某种映射。以及它们各自的库表示。由于此过程也未标准化( see this thread )并且此过程比 C 的 1 到 1 映射复杂得多。 ,不同编译器甚至编译器版本的 ABI 可能有任何不同。
现在给定两个编译器(或链接器,我找不到指定的资源,其中一个完全负责修改,但由于此过程未标准化,因此也可以外包给 cthulhu)具有不同的名称修改方案,创建以下函数入口点(简化):

compiler1
_a_
_a_int_
_a_char_

compiler2
_a_NULL_
_a_++INT++_
_a_++CHAR++_
不同的链接器不会理解您特定进程的输出; linker1将尝试搜索 _a_int_在仅包含 _a_++INT++_ 的库中.由于链接器不能使用模糊字符串比较(这可能会导致天启,恕我直言)它不会在库中找到您的函数。也不要被这个例子的简单性所迷惑:对于每个特性,如命名空间、类、方法等,都必须实现一个方法来将函数名称映射到入口点或内存结构。
鉴于您的示例,您很幸运,您使用的是同一出版商的库,他们编写了一些逻辑来检测旧库。通常你会得到类似 <something> could not be resolved 的东西。或其他一些令人费解、恼人和/或无用的错误消息。
一些关于 Visual Studio 和库的一般信息和经验转储:
  • 一般来说,Visual C++ 套件不支持不同版本之间的交叉链接库,但你可能很幸运并且它可以工作。不要依赖它。
  • 自 VC++ 2015 起,微软保证库的 ABI 与 drescherjm commented 兼容。 :link to microsoft documentation
  • 通常,在使用来自不同套件的库时,您应该始终保持谨慎,因为 n. 1.8e9-where's-my-share m. commented here (here is your share btw)关于对其他库和运行时的依赖。一般来说,无法控制库的构建方式是一个巨大的问题

  • Tzigs answer 外,还编辑寻址内存布局不兼容问题:不同的名称修改方案似乎部分是为了保护用户免受不兼容库的链接。 This answer详细介绍它。相关文章来自 gcc docs :

    G++ does not do name mangling in the same way as other C++ compilers. This means that object files compiled with one compiler cannot be used with another.

    This effect is intentional [...].

    关于c++ - 为什么旧编译器构建的某些库可以链接到现代代码,而其他库则不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68472555/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com