C++ 二进制兼容性

| 分类 C-Family  | 标签 binary  compatibility 

前两天扫了一眼 JNI 的一部分代码,被长达 22 个参数的函数着实震惊了一把,而且从文件历史上看,参数个数近来仍在增长中。每次增长之后,一旦 Java 代码和 C 库不匹配,App 总是直接 Crash 掉。这个问题的解决办法暂且不谈,但它让我想起了另外一个问题:二进制兼容性 (Binary Compatibility)。摘录一下。

1 二进制兼容与源代码兼容

如果一个应用程序动态链接到一个共享库,并且该库更新之后,应用程序无需重新编译即可继续使用,则该动态库具有 二进制兼容性 (Binary Compatibility)

相对的,如果应用程序需要重新编译才能运行,则该库具有 源代码兼容性 (Source Code Compatibility)

而如果应用程序必须修改源代码才能编译运行,通常我们称其为不兼容。

2 The Do's and Don'ts

简单来说,如果修改了某些个类,但是这些修改并没有改变类实例的内存布局(实例大小以及类的虛函数表 (Virtual Function Table)) ,则该改动通常具有二进制兼容性,反之则不具备。

2.1 The Do's

下列操作通常不会引起二进制兼容问题:

  • 增加新的非虛成员函数
  • 为类增加新的静态方法
  • 为一个类增加新的枚举类型
  • 为枚举类型添加新的定义
    这里有个极端的情况:新定义的值过大导致编译器重新为枚举选择新的基本类型 (Underlying Type)。这会导致库文件以及引用了该枚举的类的内存布局的变化,从而导致不兼容。
  • 更改内联函数的实现或改内联函数为非 inline
    内联函数在编译期展开,链接到该动态库的程序其实已经包含了该函数的实现,因此不会使用到库里面相关的改动,因此是兼容的。但该方法过于 tricky。
  • 删除私有的非虚函数。
  • 删除私有静态成员变量。

2.2 The Don'ts


上一篇     下一篇