gpt4 book ai didi

c++ - 混合 libstdc++ 版本

转载 作者:可可西里 更新时间:2023-11-01 17:57:40 28 4
gpt4 key购买 nike

有 2 个软件团队为同一操作系统 (Scientific Linux 6.5) 开发 C++ 应用程序:

Team_A 使用操作系统提供的编译器和库(GCC 4.4.7、GLIBC_2.12、GLIBCXX_3.4.13)来构建其 C++98 应用程序和各种共享库。

Team_B 使用从源代码构建的较新 GCC 版本 (4.8.3)。它是一个本地编译器,它链接到 OS libc,并使用 OS 标准头文件,但有自己的 stdc++ 版本 (GLIBCXX_3.4.19)。 Team_B 在 C++11 模式下使用此编译器构建其应用程序 (AppB),并随它一起部署 libstdc++ 和 libgcc_s。

Team_A 以共享库(.so、.hpp)的形式为 Team_B 提供服务:LibA。该库的API是一组C++类(在头文件中声明,在.so中实现),方法以std::string和其他stdc++类为参数。

此时我们遇到了问题:AppB 构造 GLIBCXX_3.4.19 C++11 风格的 std::whatever 对象并将它们传递给 LibA,后者将它们解释为 GLIBCXX_3.4.13 C++98 风格的对象,这可能不会向前兼容。

这是个问题吗?它会导致应用程序崩溃吗? std::whatever 实现是否在版本之间兼容(相同的内存布局)? C++98 与 C++11 相比如何?

一些让我更加困惑的情节曲折:

  • AFAICT,当 AppB 运行时,只有一个 libstdc++ 被加载,较新的一。即使 LibA 链接到旧的,它也不会被加载。
  • 但是 libstdc++ 中的符号是有版本控制的。所以,如果 LibA 显式使用一个符号的旧版本,它将被链接到那个。这表示AppB 将使用相同功能的 2 个不同实现和 LibA。
  • std::string 和 containters 是模板类,这意味着它们的一部分实现最终在它生成的地方结束,一部分在 libstdc++.so 中。即使加载了较新的 libstdc++,生成的LibA 中的模板代码来自旧版本。

我想了解在这种情况下到底发生了什么,是否存在风险和无效问题。让团队处于相同的开发环境中不是一种选择。从 API 中删除 std::类也非常困难。

欢迎指点! :)

最佳答案

与 C 不同,C++ 没有定义的 ABI。这意味着......

  1. C++ 重整可能会改变 wikipedia : name mangling .请注意 Alpha 名称修改是如何改变的。
  2. 类的结构可能不同。对于结构的 protected:private:public: 部分的布局可能会有不同的决定。 vtable 的位置和含义可以在编译器之间移动。不同编译器版本之间可能存在不同的预定义函数,例如 vtable 中的 typeinfo。
  3. STL 中结构的实现可能因 C++ 版本而异(例如,字符串共享在早期的 Visual Studio 实现中完成,但在 C++11 中已被禁止)。
  4. 在 Windows 中,不同的运行时可能会以不同的方式管理它们的内存(绑定(bind)到不同的 malloc/free)。传递完整的对象或指针时,这可能会导致调用不正确的自由实现。

您可以做些什么来缓解这些问题?

源码分享

不是提供已编译的库,而是将服务作为源代码交付,以便在同一环境中编译。

标准化 libstdc++

源代码构建的编译器,可以用旧的 stdC++ 重新构建。这将限制第 3) 点的影响。

创建外观

两个团队之间有一个接口(interface),需要说一种共同的语言。这种语言可能应该是 C。

团队 A => C++ 外观/ stub => C 接口(interface) => C++ 外观/代理 => 团队 B。

立面应该建在它使用的环境中。

关于c++ - 混合 libstdc++ 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27881022/

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