动态链接&编译

涉及到C编译相关的一些知识

Posted by tianchen on September 28, 2019

动态链接库

  • 库本质上是可执行代码的二进制形式,可以直接load进内存当中执行
  • Linux中的xxx.so(shared object)和Win下的.dll(dynamic linked library)
    • 静态库与之对应有(.a和.lib)
  • 编译分3步走
    1. 预处理
      • 主要进行了一些文本处理(#开头的一些语句)
        • 进行宏替代等
          • include可以看做将整个文件复制到了这个文件当中
          • define可以看做对整个文件进行了一个替换
          • ifdef ifndef undef if 只保留符合条件的语句,否则删除
          • 🤔define的东西对include的文件会不会有影响?两者的先后顺序是否会对执行结果造成不一样
    2. 编译
      • 将.c的源文件转化为.s的汇编文件(进行语法检查之类的)
      • 对于一些外部的变量,编译的过程不会检查它的具体实现
    3. 汇编
      • 将汇编语言程序转化为机器码,二进制文件,该文件也叫做目标文件(.o/.obj)
    4. 链接
      • 连接函数以及外部变量
      • dll发生在这个步骤
        • 静态链接:将汇编生成的xxx.o与引用的库一起打包到可执行文件xx.exe中 (物理连接,直接复制了一份包括到编译文件中)
        • 动态链接 在该过程中并不是实际将引用库一起打包进去,只是保留了一个到对应库的连接
  • 静态链接
    • 可以认为是一个巨大的免安装运行文件(与之对应的正常采用动态链接库的软件的安装过程中就是在部署dll)
    • 更新依赖麻烦,占用空间大
    • 编译的时期完成链接,程序实际运行的时候和函数库并没有交互(比如完成编译之后再对函数库进行了更新和改进,对这个可执行文件没有用)
  • 动态链接
    • 如果同时有多个程序调用了某个dll,那么在内存中只需要存储一份副本
  • 预编译
    • .pch预编译头文件
  • linux中使用ldconfig来更新动态链接库的依赖
    • 本质是更新了/etc/ld.so.cache