当前位置: 首页 > news >正文

设计心得——API和ABI以及ABI的兼容性

一、工程实践需求

在开发的工程实践中,经常会遇到这些情况,在升级了动态库或相关的程序后,项目整体就无法启动了。甚至可能在运行时,直接就崩溃了。而在互联网的应用中,更愿意使用热补丁,即在不停止整体服务的情况下,替换相关的库(即不需要项目工程整体进行重新编译)。但很多情况下,这种需求的可能性是无法实现的,特别是在C++的应用中更是如此。一般来说,动态库HELL和上面的说明也有密切的关系。所以本文提到的问题主要是以动态库为主。
要想实现上述的问题,就需要提到C++的二进制兼容的问题,也就是今天重点分析的技术点。

二、ABI和API

API可能广为开发者熟悉,只要真正的做过开发的就一定接触过API,Application Programming Interface,应用程序编程接口。API是对外的(供开发者调用),API的种类划分方式有很多,包括按用途、系统、网络、硬件、范围等等。其核心的作用是:

  1. 分层和模块化处理
  2. 功能重用
  3. 安全和解耦
  4. 部署、测试等
    API并不是本文的重点,主要是引出ABI,Application Binary Interface,二进制应用接口。ABI是对内的(供机器调用的),主要用来处理多个二进制程序可以共同启动并运行。ABI在不同的平台上可能有不同的标准。比如在常见的X64平台上,就有Windows x64 ABI(MSVC C++ ABI)和 x86-64 System V ABI(Itanium C++ ABI )。不管是哪种ABI,其本质都是为协调在平台上的二进制的兼容性。它主要包括:
  5. 支持的处理器的指令集即各种CPU的支持机制
  6. 处理的基础类型、内存大小、内存布局以及对齐方式等各种数据表示机制
  7. 函数(包括虚函数机制)的调用机制、传参机制、栈的处理机制以及寄存器的应用方式(如返回值的寄存器处理、函数参数的寄存器应用方式等等)即函数调用约定机制
  8. 二进制文件的格式(这个非常重要,如ELF还是PE),即目标文件格式处理机制
  9. 操作系统或底层库(如Runtime Library)系统接口调用机制

开发者都知道要保证API的稳定性,但稳定的API并不一定能保证ABI的稳定和兼容性。API的升级可能导致ABI的不兼容从而导致程序运行的异常。API不兼容只会导致代码无法编译,而ABI不兼容则可能导致程序的无法运行。只有深刻的掌握了上述的机制,才能够从基础真正理解ABI的关键所在。而所谓的跨平台开发中,ABI兼容是一个非常被容易忽视的问题,往往在出现问题后才引起开发者的重视。

三、ABI兼容的控制

在了解了上述的相关ABI兼容的内容后

  1. 很可能影响ABI接口的开发方式
    a)类的继承和多态:增加或移除虚拟函数;增加或移除继承;修改继承体系内的类的成员顺序;重写多态函数
    b)类的各种限定、修饰符及数据类型等:如移除CV限定符或final、noexcept(当然如果确实无异常没有问题)等;修改返回值类型、参数类型、扩展或缩减参数以及权限控制等等
    c)类成员函数的控制:重载函数的增加及内联的控制(普通转内联 );对导出函数删除或更改函数签名等
    d)类成员变量控制:增加或删除非静态成员变量;改变其声明的顺序;对静态成员移除或取消导出,修改类型及更改CV限定符
    e)导出类的控制:取消或删除导出类
    f)模板类:任何修改模板参数的行为,如增、删、重排序等

  2. 不大可能影响ABI兼容性的开发方式
    a)类的继承:在严格控制下(如无多态),可对其按照下面的类成员进行修改
    b)枚举的控制:在现有的枚举内增加枚举定义
    c)类成员函数的控制:添加普通函数(含构造函数);删除非导出函数;修改函数参数默认值;增加函数的noexcept;修改函数名称;增减友元函数的声明
    d)类成员变量控制:修改成员变量名称;添加新的静态成员变量(不影响类的内存布局)
    e)导出类的控制:增加新的导出类
    f)宏控制:不会影响到接口本身导出的宏的修改和增加

四、ABI兼容问题实践

下面将针对影响ABI兼容控制相关的编程方法进行举例说明:

  1. 内存布局和内存对齐
    下面为导出的数据结构体定义:
//升级前structData{inti;charc;};//升级后structData{inti;charc;doubled;};//再升级后structData{charc;doubled;inti;};

增加了导出变量和修改了成员定义顺序后(占用空间不同)都可能导致ABI的稳定性。
2. 虚函数

//升级前structData{virtualvoidgetData(){}};structSubData:public Data{virtualvoidgetData(){}};//升级后structData{virtualvoidsetData(){}virtualvoidgetData(){}};structSubData:public Data{virtualvoidsetData(){}virtualvoidgetData(){}};

虚拟函数的修改会导致多态行为的接口改变影响ABI稳定性。
3. 参数和返回值的寄存器处理

//升级前structData{inta;intb;};class Demo{public:DatagetData(){}intsetValue(constData&d){}};//升级后structData{inta;intb;doubled;};class Demo{public:DatagetData(){}intsetValue(constData&d){}};

这种情况增加了成员影响了返回值的处理。特别是在传参处理上,有些平台允许将16字节大小的结构体拆成两个8字节的部分使用寄存器传参。
4. 编译器处理
编译器选项的选择对ABI的影响也不小,比如优化级别:-O1,-O2等等;RTTI控制-fno-rtti;字节对齐-fpack-struct[=n] 等等。不同的平台可能相关编译选项也有不同,可参看相关的文档工具查看
5. 其它
还有不少的细节可以控制和影响ABI兼容性,如调用约定、其中有一个解决机制非常不错,在前面也分析过,0长度数组:

structData{inta;intb;charbuf[0];};

这种方式就可以既兼容ABI的稳定又可以在一定程度上扩展相关的数据。不过,它不是在所有平台通用的,需要注意。

五、常用的ABI兼容方法

虽然实现C/C++的ABI兼容难度很大,但在工程实践中也总结了几个不错的办法。主要有:

  1. 使用位域
    直接操作位对于任何的平台来说,基本都是一样的,所以它可以最大可能的保持ABI兼容
  2. 使用Pimpl机制,尽最大可能的隔离隐藏。这样,就把ABI的兼容性隔离到了一个很小的范围内
  3. 使用隔离隐藏机制,如上面提到的零长度数组和类分布式的方法如消息、事件等,隐藏ABI兼容的细节
    除了上述的开发上的技术应用外,还可以在技术管理上进行控制:
  4. 应用静态库。这个就不用解释了,全包含了,哪里还有什么升级、替换的问题。不过,静态库也有其缺点,要慎重
  5. 严格控制动态库的版本管理 ,防止DLL HELL的问题

六、总结

其实ABI兼容问题,对于C/C++这种中低级语言来说是一个大问题。但对于更现代的高级语言,ABI兼容已经被隔离在了开发之外,像C#和Java等,它们很多都运行在各自的虚拟环境上,很多ABI兼容的细节问题自然已经被屏蔽掉。有些问题会随着技术的演进而自然被解决掉。这也是那句名言,要用发展的眼光看问题。

http://www.jsqmd.com/news/332903/

相关文章:

  • 苏州GEO优化服务商品牌推荐,聚合AI多行业赋能成就营销佳绩 - mypinpai
  • 西安装修设计厂商2026口碑排行,设计服务新标杆,外墙仿石漆/全屋定制/自建房建设/垫层/pur封边,装修设计企业推荐 - 品牌推荐师
  • 详细介绍:linux 信号
  • C#: 如何从全局捕获所有线程的异常
  • 解析广东靠谱的移民公司年度排名,移民公司求推荐看这里 - 工业推荐榜
  • 显卡性能优化工具:DLSS版本管理效率提升指南
  • GitHub 热榜项目 - 日榜(2026-02-02)
  • 如何用学术效率工具解决中文注释格式化难题:提升文献管理效率的技术方案
  • WordPress如何实现WORD文档图片的无损保存至博客?
  • 艾尔登法环存档无忧迁移全流程:从数据解析到跨设备同步的技术指南
  • 网页前端用WordPress导入WORD文档时,如何保留粘贴的图片格式?
  • Android 基础入门教程4.1.2 Activity初窥门径
  • Word表格题注自动设置全攻略
  • ​ Android 基础入门教程​4.1.3 Activity登堂入室
  • 计算机毕业设计springboot摊位管理系统分析与设计 基于SpringBoot的集市摊位租赁与运营平台设计与实现 SpringBoot驱动的智慧夜市摊位综合管理系统研发
  • Kanass零基础学习,如何快速导入Jira、Mantis数据 - 实践
  • 山西现房市场中的学区选择:近期交付项目一览,学区房/70年大产权住宅/新楼盘/实景现房/南都新城,学区房厂商怎么选择 - 品牌推荐师
  • 2026年服务口碑佳的粉碎型格栅供应商有哪些?内进流网板式细格栅/污水处理粉碎型格栅,格栅供应商怎么选择 - 品牌推荐师
  • 2026年沈阳可靠的汽车贴膜店铺附近推荐,玻璃膜/沈北贴膜/隐形车衣/贴车衣/太阳膜/车衣改色,汽车贴膜门店哪家好 - 品牌推荐师
  • 北京装修机构推荐哪家,一诺原创空间设计一体化服务让人省心 - 工业品牌热点
  • 北京全屋装修服务哪家好,优选世家整装局改值得关注 - 工业品牌热点
  • 分析合肥中锐学校图书馆藏书量,藏书多吗,能满足学生需求吗? - 工业品网
  • KTV装修定制生产厂的价格如何,香河森源家具厂贵不贵? - 工业推荐榜
  • CW32L010实现电压监测
  • 探讨苏州GEO优化服务商口碑怎样,用户评价和反馈好不好 - 工业推荐榜
  • 2026年河北地区KTV装修定制一站式服务公司年度排名 - 工业设备
  • 【MySQL修炼篇】从踩坑到精通:事务隔离级别的3大异常(脏读/幻读/不可重复读)解决方案
  • 2026年万洲金业交易软件下载,了解费用价格开启投资之旅 - myqiye
  • 山西诚信的药品追溯码采集仪企业口碑哪家好 - 工业品网
  • 2026年陕西靠谱的密封橡胶地垫、橡胶块及工作指示牌品牌推荐 - myqiye