GCC与MS C++编译器,用于维护API向后二进制兼容性

lin*_*ild 19 c++ gcc backwards-compatibility visual-c++ itanium-abi

我来自Linux世界,并且知道很多关于维护用C++语言编写的动态库API的向后二进制兼容性(BC)的文章.其中之一是基于Itanium C++ ABI的"使用C++的策略/二进制兼容性问题",它由GCC编译器使用.但我找不到类似的Microsoft C++编译器(来自MSVC).

我知道大多数技术都适用于MS C++编译器,我想发现与ABI差异相关的编译器特定问题(v表格布局,修改等)

所以,我的问题如下:

  • 你知道维护BC时MS C++和GCC编译器之间有什么区别吗?
  • 在哪里可以找到有关MS C++ ABI的信息或在Windows中维护API的BC?

任何相关信息将受到高度赞赏.
非常感谢你的帮助!

Art*_*yom 22

首先,这些政策是一般的,不仅仅是指gcc.例如:函数中的私有/公共标记是MSVC特有的,而不是gcc.

所以基本上这些规则也完全适用于MSVC和通用编译器.

但...

你应该记住:

  1. 自3.4发布以来,GCC/C++保持其ABI稳定,并且大约7年(自2004年以来),而MSVC在每个主要版本中都打破了其ABI:MSVC8(2005),MSVC9(2008),MSVC10(2010)彼此不兼容.
  2. 与MSVC一起使用的一些频繁标志也可以破坏ABI(如异常模型)
  3. MSVC具有不兼容的调试和释放模式的运行时间.

所以是的,你可以使用这些规则,但正如MSVC的通常情况一样,它有更多的怪癖.

另请参阅" 关于二进制兼容性的一些想法 ",并且Qt也使它们与MSVC保持ABI稳定.

注意我在CppCMS中遵循这些规则时有一些经验

  • @Rup - 是的,运行时不兼容,默认值已更改,例如在MSVC7和MSVC8之间,wchar_t的默认含义已更改,依此类推.所以基本上,混合使用不同编译器版本编译的库是非常糟糕的. (3认同)

Tob*_*ner 8

在Windows上,您基本上有两个长期二进制兼容性选项:

  1. COM
  2. 模仿COM

看看我的帖子.在那里,您将看到一种在不同的编译器和编译器版本中以二进制兼容的方式创建DLL和访问DLL的方法.

C++ DLL插件界面


Ash*_*ain 7

MSVC二进制兼容性的最佳规则是使用C接口.根据我的经验,您可以使用的唯一C++功能是单继承接口.因此,将所有内容表示为使用C数据类型的接口.

这是一个二进制兼容的东西列表:

  • STL.二进制格式即使在调试/发布之间也会发生变化,并且取决于编译器标志,所以最好不要使用STL跨模块.
  • 堆.不要new/ malloc在一个模块中和delete/ free在另一个模块中.有不同的堆彼此不了解.STL无法跨模块工作的另一个原因.
  • 例外.不要让异常从一个模块传播到另一个模块.
  • 来自其他模块的RTTI/dynamic_casting数据类型.
  • 不要相信任何其他C++功能.

简而言之,C++没有一致的ABI,但C确实如此,因此避免C++功能跨越模块.由于单继承是一个简单的v表,因此可以有效地使用它来公开C++对象,前提是它们使用C数据类型并且不进行跨堆分配.这也是Microsoft自己使用的方法,例如Direct3D API.GCC可用于提供稳定的ABI,但标准不要求这样,并且MSVC利用这种灵活性.

  • 是的,这是"依赖于编译器标志"的一部分,这是你不能信任ABI的另一个原因. (2认同)