美文网首页
静态库和动态库

静态库和动态库

作者: Abner_XuanYuan | 来源:发表于2023-03-14 20:35 被阅读0次

    1、库

    库是程序代码的集合,是共享程序代码的一种方式。库本质上是一种可执行代码的二进制格式,可以被载入内存中执行。

    2、库的分类

    1、开源库:源代码是公开的,可以看到每个文件(.m 文件)的实现。如:AFNetworking、SDWebImage 等。
    2、闭源库:不公开源代码,是经过编译后的二进制文件,看不到具体的实现。闭源库又分为:静态库和动态库。

    1、linux 中静态库和动态库区别
    静态库:库的名字一般是 libxxx.a。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中。
    优点:编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。
    缺点:如果静态函数库改变了,那么程序必须重新编译。
    动态库:库的名字一般是 libxxx.so。相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响程序,所以动态函数库的升级比较方便。

    2、iOS 开发中静态库和动态库区别:
    静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。
    静态库的好处
    1、模块化,分工合作,提高了代码的复用及核心技术的保密程度。
    2、避免少量改动经常导致大量的重复编译连接。
    3、可以重用,但不是共享使用。
    动态库的好处
    1、使用动态库,可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,进行分工,影响比较小。
    2、使用动态库,多个应用程序共享内存中得同一份库文件,节省资源。
    3、使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。
    4、应用插件化。
    5、软件版本实时模块升级。
    6、在其它大部分平台上,动态库都可以用于不同应用间共享, 共享可执行文件,这就大大节省了内存。苹果系统专属的 framework 是共享的,但是我们自己使用 Cocoa Touch Framework 制作的动态库是放到 app bundle 中,运行在沙盒中的。

    3、静态库和动态库的存在的形式

    静态库:以 .a 和 .framework 为文件后缀名。
    动态库:以.tbd/.dylib 和 .framework 为文件后缀名。
    区别:.a 是一个纯二进制文件,.a 要有 .h 文件以及资源文件配合;.framework 中除了有二进制文件之外还有资源文件,.framework 文件可以直接使用。
    总结:.a + .h + sourceFile = .framework。所以创建静态库最好还是用 .framework 的形式。
    注:系统直接提供给我们的 framework 都是动态库。

    4、静态库和动态库的区别

    1、区别

    不同点
    1、静态库在链接时,会被完整的复制到可执行文件中,如果多个 App 都使用了同一个静态库,那么每个 App 都会拷贝一份,缺点是浪费内存。
    2、动态库不会复制,只有一份,程序运行时动态加载到内存中,系统只会加载一次,多个程序共用一份,节约了内存。
    共同点
    静态库和动态库都是闭源库,满足某个功能的使用,不会暴露内部具体的代码信息。

    2、静态库的处理方式

    对于一个静态库而言,其实已经是编译好的了,类似一个 .o 的集合这里并没有连接。在 build 的过程中只会参与链接的过程,而这个链接的过程简单的讲就是合并,并且链接器只会将静态库中被使用的部分合并到可执行文件中去。

    静态库
    1、链接器会将所有 .o 用到的 global symbol 和 unresolved symbol 放入一个临时表,而且是 global symbol 是不能重复的。
    2、对于静态库的 .o , 连接器会将没有任何 symbol 在 unresolved symbol table 的给忽略。
    3、unresolved symbol 类似 extern int test(); --- **.h **的 声明?
    4、global symbol 类似 void test() { print("test")} -- .m 的 实现?
    5、最后,链接器会用函数的实际地址来代替函数引用。
    3、动态库的处理方式

    1、对于动态库而言其实分动态链接库动态加载库两种,这两个最本质的区别是加载时间。
    动态链接库:在没有被加载到内存的前提下,当可执行文件被加载,动态库也随着被加载到内存中。在 Linked Framework and Libraries 设置的一些 share libraries。【随着程序启动而启动】
    动态加载库:当需要的时候再使用 dlopen 等通过代码或者命令的方式来加载。【在程序启动之后】
    2、但是不论是哪种动态库,相比较与静态库,动态库处理起来要棘手的多。由于动态库是动态的,所以你事先不知道某个函数的具体地址。因此动态链接器在链接函数的时候需要做大量的工作。

    示例

    1、当我们点击了 build 之后,做了什么事情呢?

    1、预处理(Pre-process):把宏替换,删除注释,展开头文件,产生 .i 文件。
    2、编译(Compliling):把之前的 .i 文件转换成汇编语言,产生 .s 文件。
    3、汇编(Asembly):把汇编语言文件转换为机器码文件,产生 .o 文件。
    4、链接(Link):对 .o 文件中的对于其他的库的引用的地方进行引用,生成最后的可执行文件(同时也包括多个 .o 文件进行 link)。

    相关文章

      网友评论

          本文标题:静态库和动态库

          本文链接:https://www.haomeiwen.com/subject/rnekrdtx.html