动态库(.so)与静态库(.a)的主要区别在于链接阶段与运行特性:
编译阶段差异
静态库:在编译时被完整链接进目标程序,成为可执行文件的一部分。因此,程序运行时无需外部依赖,但会导致可执行文件体积较大。 就是程序link的时候就把静态库中的东西取出来,放到生成的可执行文件中,当这个可执行文件执行时,就不需要再次调用这个静态库了。
动态库:编译时仅记录引用关系,不直接包含代码,程序运行时由系统动态加载。可执行文件体积较小,但需依赖外部.so文件。 就是程序link的时候,只是将库中的 符号包含,并没有包含静态库里的内容,等到可执行程序在执行 时,需要依赖动态库中的内容,也就是“随用随取”
运行特性
静态库生成的程序启动更快,且无需运行时依赖外部文件,但更新时需重新编译程序。
动态库支持运行时更新(如通过动态下载.so文件),但可能增加启动延迟和运行时依赖风险。
在linux编程中,对于静态库和动态库,在makefile中引用方式一模一样,只不过如果使用动态库,我们需要将动态库拷贝到目标系统中,比如拷贝到usr/lib下,然后可执行程序才能正常执行。而对于静态库,只要我们编译链接成功生成可执行文件,就不需要再目标系统中再拷贝了,因为可执行文件中已经包含了静态库的全部。
静态库和动态库的优缺点也是明显的,对于静态库,只要编译链接成功,只需要将可执行文件放到目标板上,就可以直接执行,而不用再拷贝静态库了,一次性的,执行效率也更高一些,缺点是当静态态库升级,则需要重新编译链接。而对于动态库,不仅需要将可执行文件拷贝到目标板上,还需要将动态库也拷贝到目标板上,缺点是执行速度相对慢一些。不过优点就是,当动态库升级时,我们只需要将动态库重新拷贝到目标板上,而可执行程序并不需要重新编译链接(前提是动态库接口不变)。
适用场景
静态库适合功能固定、无需频繁更新的场景,例如系统级组件或基础功能库。
动态库更适合模块化开发或需要频繁更新的场景,例如第三方应用或插件化开发。
Android特有差异
每个应用有独立的沙盒环境,即使使用动态库,不同应用仍需打包自己的.so文件,无法实现跨应用共享(除非系统级预装库)。
静态库会使主可执行文件体积增大,但更新时无需重新编译其他模块。
参考文章

1768

被折叠的 条评论
为什么被折叠?



