混合libstdc ++版本

Gyo*_*ely 8 c++ gcc c++11

有两个软件团队为同一个OS(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 ::无论什么对象并将它们传递给LibA,后者将它们解释为GLIBCXX_3.4.13 C++ 98样式对象,这可能不是向前兼容的.

这是一个问题吗?它会导致应用程序崩溃吗?std ::的任何实现是否兼容版本(相同的内存布局)?那么c ++ 98和C++ 11呢?

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

  • AFAICT,当AppB运行时,只有一个libstdc ++加载,更新的.即使LibA与旧版本链接,也不会加载.
  • 但是libstdc ++中的符号是版本化的.因此,如果LibA明确使用旧版本的符号,它将与之相关联.这意味着AppB和LibA将使用相同功能的2种不同实现.
  • std :: string和contains是模板类,这意味着它们的实现的一部分最终会在它生成的地方生成,其中一部分在libstdc ++中.所以.即使加载了较新的libstdc ++,LibA中生成的模板代码也是旧版本.

我想了解在这种情况下究竟发生了什么,如果它有风险,并且无效问题.让团队处于相同的开发环境不是一种选择.从API中删除std :: classes也很难.

欢迎任何指示!:)

mks*_*eve 3

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

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

您可以采取什么措施来缓解这些问题?

源码分享

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

libstdc++ 标准化

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

创建立面

两个团队之间有一个接口,需要使用共同语言。这种语言可能应该是 C。

团队 A => C++ 门面/存根 => C 接口 => C++ 门面/代理 => 团队 B。

立面应建在其使用环境中。