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

时间:2011-01-24 13:46:53

标签: c++ visual-c++ gcc backwards-compatibility itanium-abi

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

据我所知,大多数技术都适用于MS C ++编译器,我想发现与ABI差异相关的编译器特定的问题(v-table布局,修改等)< / p>

所以,我的问题如下:

  • 在维护BC时,您是否知道MS C ++和GCC编译器之间存在任何差异?
  • 我在哪里可以找到有关MS C ++ ABI的信息或在Windows中维护API的BC?

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

3 个答案:

答案 0 :(得分:22)

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

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

但是...

你应该记住:

  1. GCC / C ++自3.4发布以来保持其ABI稳定并且大约7年(自2004年以来),而MSVC在每个主要版本中打破其ABI:MSVC8(2005),MSVC9(2008),MSVC10(2010)与之不兼容彼此。
  2. MSVC使用的一些频繁标志也可以破坏ABI(如异常模型)
  3. MSVC的调试和发布模式的运行时间不兼容。
  4. 所以是的,你可以使用这些规则,但正如MSVC的通常情况一样,它有更多的怪癖。

    另见“Some thoughts on binary compatibility”,Qt也保持ABI与MSVC的稳定。

    注意我在CppCMS

    中遵循这些规则时有一些经验

答案 1 :(得分:8)

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

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

    C++ DLL plugin interface

答案 2 :(得分:7)

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

以下列出了二进制兼容的内容:

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

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