动态链接库和静态链接库

170 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

动态链接库的格式

  • Linux

    • lib{name}.so
    • linux 只会去环境变量中设定的地址和 /usr/local/lib 路径下调用动态链接库
    • 通过 LD_LIBRARY_PATH 这个系统名来设定 动态链接库地址
    • 因此我们现在会明白为什么安装某些软件会需要设定环境变量,因为程序的运行需要去安装位置调用动态链接库
  • Windows

    • .dll

player.bilibili.com/player.html…

main 文件

#include <stdio.h>
// 这个是自定义的头文件,里面包含对动态链接库的函数定义
#include "math.h"

int main() {
    int j = k = 1;
    // add函数是
    int i = add(j,k);
    return i ;
}

math.h 头文件

// 只包含了函数的声明,主要是为了方便其他模块的引用
void add(int i,int j);

math.c 头文件的源文件

// 对函数的具体实现

libmath.so 动态链接库文件

  • 该文件是math.c 文件经过编译得来的
  • gcc -shared -fPIC math.c -o libmath.so
    • -o 指定要输出的文件名

    • -shared 表明这是一个共享库

    • -fPIC是为了直到函数运行时才真的设定真实函数地址

对main文件进行编译

  • gcc main.c -lmath -L. -o main
    • -lmath 表示main 中动态链接库的名称,其省略了lib 和后缀.so (libmath.so -- > lmath)
    • -L 指定动态链接库文件所在的地址 上面的那个点表示的是他们在同一个文件夹下
  • 因此我们就得到了动态链接的主程序 main
  • 在运行main程序之前我们还需要保证系统可以找到当前自定义的动态链接库,方法有两个
      1. 因为linux默认情况下只会去 /usr/local/lib 路径下找.so文件,因此可以将动态链接库拷贝过去
      • sudo cp libmath.so /usr/local/lib
      1. 将动态链接库文件所在的地址加入到环境变量中 LD_LIBRARY_PATH 这个变量就是用来找动态库的,因此我们可以明白,为什么安装某些软件需要去配置环境变量
      • export LD_LIBRARY_PATH = "$(pwd)"

动态链接库和静态链接库的区别

  • 动态链接库相对于静态链接库的一个优点在于更新较为方便,因为动态链接库是独立的文件,所以只需要修改后重新编译就好,不会对别的程序有影响,而静态链接库是存放在程序中了,对静态文件修改就需要对整个程序重新编译。
  • 静态链接库在链接阶段就和程序整合到了一起,函数地址的重定位在这个阶段已经完成。但是动态链接库将这个过程推迟到了运行时,在运行时将主程序和所有的动态链接库都加载到内存中,这个时候内存会根据情况给这些链接库分配内存地址,这个时候就可以对函数进行重定位了。