静态库与动态库相关知识…

库文件分为静态库和动态库(共享库)。

静态库

Linux为.a,window上为.lib

静态库是中间文件的集合,在链接阶段直接将库中的内容合并到最终的可执行文件中,链接完成后,生成的可执行文件的执行不再依赖静态库。

静态库生成的命令

1
2
gcc -c *.c  # 先将.c文件生成对应的.o文件
ar crv libxxxx.a *.o # 其中xxxx是生成的库名,前面的`lib`和后面的`.a`必须有

静态库的使用

  • 方法一:gcc -o run main.c -L(库路径) -l(库名),例如:
    1
    gcc   -o  run  main.c   -L/home/stu/lib   -lList
  • 方法二:gcc -o run main.c 路径/libxxxx.a,例如:
    1
    gcc  -o  run   main.c   /home/stu/lib/libList.a

动态库

Linux上为.so,Window上为.dll

动态库是不可单独执行的可执行文件,链接阶段只在可执行文件中设置使用的的库,运行时由操作系统加载到内存上执行,因此生成的可执行文件在执行时要依赖动态库的存在。

动态库生成的命令

1
gcc -shared -fPIC -o libxxxx.so *.c

-fPIC参数,多个应用程序加载动态库时,系统只有一个so代码段。如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy。每个copy都不一样,取决于这个.so文件代码段和数据段内存映射的位置。

动态库的使用

同静态库一样。

当链接完成后执行时会有问题,问题出现的原因是:动态库需要由操作系统加载到内存上,但操作系统找不到自定的库,因此依赖动态库而的程序不能直接运行会出错!解决这个问题有以下两种方案:

  1. 将动态库拷贝到 /lib 或 /usr/lib 目录下,但是这个操作需要 root 权限,不建议这么做;
  2. 设置环境变量export LD_LIBRARY_PATH=动态库所在的绝对路径,或者修改文件:
    1
    2
    3
    4
    5
    vi /home/***/.bashrc //进入到.bashrc这个配置文件中
    然后在文件的最后加上一句export LD_LIBRARY_PATH=动态库所在的绝对路径

    或在/etc/ld.so.conf.d/下新建test.conf文件,文件中添加动态库所在的绝对路径,
    sudo ldconfig # 使生效

另外

ldd run查看可执行文件run中所加载的动态库。

动态库和静态库的区别

  1. 同样的程序,使用静态库比使用共享库程序更大;
  2. 静态库在编译链接是,就加入到了可执行程序中,共享库是在运行程序后动态装载;
  3. 目标主机没有静态库,程序可以运行,没有共享库,运行不了;
  4. 共享库升级后,程序不需要重新编译,可以直接被使用,静态库需要重新编写程序,链接新方法。