二进制兼容

二进制兼容

1. 什么是二进制兼容问题?

在升级库文件的时候,不必重新编译使用此库的可执行文件或其他库文件,并且程序的功能不被破坏.

2. 二进制兼容有什么好处?

保持二进制兼容性是为了确保软件的更新和升级过程更加平滑和无缝,以减少对用户和开发者的影响.

  1. 减少用户升级的难度: 如果新版本的程序能够与旧版本的程序兼容,用户在升级时无需重新编译或修改配置.这降低了用户升级的难度和成本.
  2. 避免破坏性变更: 破坏性变更可能会导致旧版本的程序无法与新版本的程序一起工作,从而造成功能中断或数据丢失.通过保持二进制兼容性,可以避免这种情况的发生.
  3. 提高用户信任度: 如果用户知道他们可以在不受影响的情况下升级软件,他们更有可能愿意使用最新版本的程序,从而提高了用户对软件的信任度.
  4. 简化发布流程: 保持二进制兼容性可以使软件发布变得更加简单,因为你不需要为每个新版本都重新构建所有的旧版本二进制文件.
  5. 降低维护成本: 如果软件能够保持二进制兼容性,你可以更轻松地维护多个版本,因为不需要重新构建和测试旧版本.

3. 实现二进制兼容有什么方法?

pimpl(pointer to implementation)

也就是说将一个类分为接口类(外观类/导出类)Foo,以及实现类.

外部使用接口类时,接口类的函数的内存偏移是固定的;而更新内容放在实现类就好了.而接口类通过一个指针,指向实现类,调用实现类的方法.这个指针就称作D指针.

3.1 什么是pimpl?

pointer to implementation 指针指向实现.简单来说就是将实现和接口分类的一种设计思路.

3.2 pimpl还有什么好处?

  • 数据隐藏 如果您正在开发一个库,尤其是专有库,则可能不希望公开用于实现库公共接口的其他库/实现技术. 要么是由于知识产权问题,要么是因为您认为用户可能会被诱使对实现进行危险的假设,或者只是通过使用可怕的转换技巧来破坏封装. PIMPL解决/缓解了这一难题.

  • 编译时间

    编译时间减少了,因为当您向XImpl类添加/删除字段和/或方法时(仅映射到标准技术中添加私有字段/方法的情况),仅需要重建X的源(实现)文件. 实际上,这是一种常见的操作.

    使用标准的标头/实现技术(没有PIMPL),当您向X添加新字段时,曾经重新分配X(在堆栈或堆上)的每个客户端都需要重新编译,因为它必须调整分配的大小 . 好吧,每个从未分配X的客户端也都需要重新编译,但这只是开销(客户端上的结果代码是相同的).

3.3 pimpl怎么实现

4. 什么时候要求二进制

  • pimpl怎么做?

    一个功能分成接口类和实现类做.

    接口类有一个D指针指向实现类,实现类有一个Q指针指向接口类.

  • D指针就可以实现二进制兼容了,为什么要引入Q指针?

    引入Q指针就是为了方便实现类使用接口类方法.

99. quiz

1. 怎样才可以保证二进制兼容?二进制兼容的关键是什么?

二进制兼容性是指一个程序的新版本可以使用旧版本的二进制接口(如共享库或对象文件)而不需要重新编译。保证二进制兼容性的关键是保持ABI(Application Binary Interface)的稳定性。

以下是一些保证二进制兼容性的方法:

  1. 不改变公共函数和方法的签名:如果你改变了函数或方法的参数类型、数量或顺序,那么二进制接口将会改变,导致二进制不兼容。

  2. 不改变数据结构的布局:如果你添加、删除或重新排序结构的成员,那么结构的布局将会改变,导致二进制不兼容。

  3. 不改变类的继承关系:如果你改变了类的基类或派生类,那么类的布局和虚函数表将会改变,导致二进制不兼容。

  4. 保持虚函数表的稳定性:如果你添加、删除或重新排序虚函数,那么虚函数表将会改变,导致二进制不兼容。

注意,以上的规则只适用于公共接口。你可以自由地改变私有函数、方法和数据成员,而不影响二进制兼容性。

2. 一般什么情况下特别要求二进制兼容?

  1. 操作系统: 操作系统的升级通常会涉及到底层的系统组件,保持二进制兼容性可以确保应用程序继续在新版本的操作系统上正常运行.

  2. 大型应用软件: 大型应用软件通常会有许多用户,升级可能涉及到大量的用户数据和配置.保持二进制兼容性有助于减少升级的风险.

  3. 软件库和框架: 开发人员在开发应用程序时可能会使用各种第三方库和框架,保持这些库和框架的二进制兼容性有助于减少对应用程序的影响.

  4. 游戏客户端: 游戏客户端经常需要进行更新和修复,保持二进制兼容性可以确保玩家在更新后继续享受游戏体验.

    如果是二进制兼容的,弄一个更新包可能就好了,如果不是的话,可能整个软件都要重新安装.