什么是库(静态库、动态库)
库:也叫做代码库,把一个或一些目标文件合并在一起方便使用,有静态库和共享库两种。
静态库:在链接时把库的二进制指令赋值到调用模块中。
动态库:也叫作共享库,会和调用者一起加载到内存,到执行调用语句时会从程序的调用位置跳转到共享库中运行。
优缺点:
静态库的优点是运行速度快,但维护麻烦,当静态库中的内容更新后需要重新编译程序,使用静态编译出的可执行文件会比共享库大。
共享库的优点是使用方便,共享库如果发生变化不需要重新编译程序,使用它编译出的可执行文件比使用静态库要小,但运行速度要比静态库慢。
注意:静态库的扩展名是.a,共享库的扩展名是.so,共享库要有执行权限。
静态库的创建和使用
1、创建
编辑静态库源码
编译出目标文件:gcc xxx.c - c
把目标文件打包成静态库文件: ar -r libxxx.a x1.o x2.o …
ar 是一个专门控制静态库的命令
-r 把目录文件合并成一个静态库,如果静态库文件已经存在则更新。
-q 向静态库中添加目录文件
-t 查看静态库中有哪些目标文件
-d 从静态库中删除目标文件
-x 把静态库展开为目标文件
2、使用
1.直接调用
把静态库当作目标文件一样,与调用者的目标文件一起合并出可执行文件。
gcc main.c libcalc.a
2.通过设置LIBRARY_PATH环境变量来指定库的路径
gcc main.c -lcalc 需要通过-l来指定库名
3.通过gcc -L参数来指导库的路径
gcc main.c _L ./calc/ -lclac
动态库的创建和使用
1、创建
编辑静态库原码
编译出目标文件:
gcc -c -fpic xxx.c -> xxx.o
把目标文件打包成共享库:
gcc -shared x1.o x2.o … -o libxxx.so
-fpic编译出位置无关代码,在代码中使用相对地址,这样共享库就可以遇到内存的任何位置。
2、使用
1、直接调用
gcc main.c libcalc.so
注意:需要设置共享的加载路径,LD_LIBRARY_PATH
2、通过设置LIBRARY_PATH环境变量来指定库的路径gcc main.c -lcalc 需要通过-l来指定库名
注意:如果静态库和共享库同时存在,优先使用共享库,通过-static可以指定使用静态库。
3、通过gcc -L参数来指定库的路径
gcc main.c -L./calc/ -lclac
4、动态加载共享库
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
功能:打开共享库
filename:共享库的路径
flag:打开方式
RTLD_LAZY:延迟加载,使用到共享库时再加载
RTLD_NOW:立即加载
返回值:成功返回共享库的句柄,失败返回NULL
void *dlsym(void *handle, const char *symbol);
功能:通过函数名在共享库中获取函数指针
handle:共享库的句柄
symbol:函数名
返回值:函数地址,失败返回NULL
char *dlerror(void);
功能:获取错误信息
int dlclose(void *handle);
功能:卸载共享库
注意:编译时添加-ldl参数
静态库和动态库的区别
二者的不同点在于代码被载入的时刻不同。
1、静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
2、动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。
3、静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
4、静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
5、动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
静态库:
优点:执行速度快;缺点:编译速度慢、编译结果大、不方便升级。
动态库:
优点:方便升级维护、编译结果小;缺点:执行速度慢。
定位头文件
头文件的三种定位方式:
1、#include “路径/xxx.h” 直接把路径写在代码中,但如果头文件路径发生变化,需要修改源代码。
2、gcc -I目录 在编译时指定加载头文件的路径。
3、设置C_INCLUDE_PATH环境变量,来添加头文件的查找路径。
打开配置文件:vim ~/.bashrc
在文件末尾添加一行内容:export export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/头文件路径
重新加载配置文件:source ~/.bashrc
env命令可以查看所有环境变量。
扩展:PATH环境变量代表是命令的查找路径,把.添加进去以后再执行程序就不需要./了。
注意:删除环境变量时需要退出终端,再重新打开