编译链接实战(27)动态库实现变了,可执行程序需要重新编译吗
文章目录
- **1. 兼容性变更(无需重新编译)**
- **场景:动态库内部实现改变,但接口不变**
- **步骤 1:创建动态库和可执行程序**
- **步骤 2:修改动态库实现(不改变接口)**
- **步骤 3:直接运行旧的可执行程序**
- **2. 不兼容变更(需要重新编译)**
- **场景 1:函数接口变更(参数类型或返回值变化)**
- **步骤 1:初始代码(同前)**
- **步骤 2:破坏接口兼容性**
- **步骤 3:尝试运行旧程序**
- **场景 2:删除或重命名符号**
- **步骤 1:初始代码(同前)**
- **步骤 2:删除 `add` 函数**
- **步骤 3:尝试运行旧程序**
- **场景 3:结构体内存布局变化**
- **步骤 1:初始代码**
- **步骤 2:修改结构体布局**
- **步骤 3:尝试运行旧程序**
- **验证工具**
- **总结**
先看结论:
(1) 兼容性变更(无需重新编译)
- 行为变更但接口不变
若动态库的内部实现逻辑改变(如修复 bug、优化算法),但以下内容保持不变:- 函数/变量的 符号名称、参数类型、返回值类型
- 结构体/类的 内存布局(如成员顺序、大小)
- 全局数据的 符号可见性
结论:无需重新编译,只需替换动态库(如libfoo.so.1.0 → libfoo.so.1.1
)。
- 仅增加新接口
在库的次要版本更新中新增函数或变量,但不影响现有接口。
结论:无需重新编译旧程序。
(2) 不兼容变更(需要重新编译)
- 接口变更
如:- 删除或重命名函数/变量
- 修改函数参数类型或返回值类型