库-10.24.25
一、概念
头文件:.h:函数声明,结构体定义,宏定义,外部引用,重定义,条件编译
#include <>:从系统路径(/usr/include)下查找
#include " ":先从指定的路径下查找,在指定路径下找不到,再去系统路径下查找
源文件:.c
库:就是把一些常用函数的目标文件打包在一起,提供相应函数的接口,便于程序员 使用;本质上来说库是一种可执行代码的二进制形式。/usr/lib或 /lib。它可以被操 作系统载入内存执行。
由于windows和linux的本质不同,因此二者库的二进制是不兼容的分为:动态库和静态库
1)静态库:静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态 库,因此体积较大。
2)动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此 在程序运行时还需要动态库存在,因此代码体积较小
动态库 静态库
linux:.so .a
windows:.dll .lib
二、库的分类
静态库和动态库,本质区别是代码被载入时刻不同。
1) 静态库在程序编译时会被连接到目标代码中。
优点:程序运行时将不再需要该静态库;运行时无需加载库,运行速度更快
缺点:静态库中的代码复制到了程序中,因此体积较大;
静态库升级后,程序需要重新编译链接
2) 动态库是在程序运行时才被载入代码中。
优点:程序在执行时加载动态库,代码体积小;
程序升级更简单;
不同应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
缺点:运行时还需要动态库的存在,移植性较差
-
三、静态库的制作
-
1、创建静态库步骤:
静态库:库会编译到程序,体积比较大,移植性,可能会被多次加载到内存,耗费内存资源,程序运行不需要库存在,可以直接运行。
gcc -c xxx.c -o xxx.o
ar crs lib名字.a *.o
使用:gcc main.c -L. -l 名字 默认生成的a.out可以直接执行
1.将源文件编译生成目标文件
gcc -c add.c -o add.o
2.创建静态库用ar命令,它将很多.o转换成.a
ar crs libmyadd.a add.o
libmyadd.a :lib指库,myadd是库名,.a指静态库
3. 静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。使用静态链 接库
gcc main.c -L. -lmyadd -o main
-L:指定链接路径
-l:链接库
4. 执行./main
2、 优缺点:
优点: 程序中已包含代码,运行时不再需要静态库。
运行时无需加载库,运行速度更快。
缺点: 静态库中的代码复制到了程序中,使程序会占更多的磁盘和内存空间
静态库升级后,程序需要重新编译链接
gcc编译四步:预处理(展开头文件,替换宏定义,删除注释)、编译(检查错误,生成汇编文件)、汇编(生成二进制文件)、链接(生成可执行文件)
- 将源文件编译生成目标文件
gcc -c xxx.c -o xxx.o
- 创建静态库,用ar命令,将许多.o文件转换成.a文件
ar crs libxxx.a xxx.o
静态库的命名规则:lib是库的前缀,xxx库名, .a后缀(扩展名)
- 测试静态库的使用
gcc xxx.c -L库所在路径 -l库名
四、创建动态库(共享库)
-
1、创建动态库步骤:
动态库(共享库):
动态库(共享库):库不编译到程序,程序体积小,移植性差,只加载一次到内存,节省内存资源,程序运行需要动态已经提前加载到内存中。
生成动态库过程:
gcc -c -fPIC xxx.c -o xxx.o
-fPIC :生成一个与地址无关的二进制文件
gcc -shared -o lib库名.so *.o
使用:gcc main.c -L. -l 库名
./a.out 执行会失败,需要提前加载到内存中再执行:
1.将动态库复制默认加载库路径中 -/lib 或 /usr/lib
2.export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库存在路径
终端执行这个指令就临时生效
放到用户主目录下的.bashrc中,该用户永久生效
放到/etc/bash_bashrc中所有用户永久生效
3.在/etc/ld.so.conf.d/中创建一个xxxx.conf的文件,文件中写库的绝对路径
1)我们用gcc来创建共享库
gcc -fPIC -c add.c -o add.o
-fPIC 创建与地址无关的编译程序
gcc -shared -o libmyadd.so add.o
2)编译代码
gcc main.c -L. -lmyadd -o main
ldd main 查看main的运行依赖那些库。
3)为了让执行程序顺利找到动态库,有三种方法 :
(1)把库拷贝到/usr/lib和/lib目录下。
sudo mv libmyadd.so /usr/lib
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. (最好是绝对路径,要在一行)
(终端关闭,环境变量就没在了)
本次配置只在当前终端有效,关闭和关机后就没效了。想要永久有效需要到 .bashrc文件 中进行修改。生效文件:source .bashrc
(3) 添加/etc/ld.so.conf.d/*.conf文件,
把库所在的路径加到文件末尾,并执行ldconfig刷新
sudo vi xx.conf
添加动态库存在的路径,如:
/home/linux/DC20111/IO/day3/share
在/etc/ld.so.conf.d下
执行:sudo ldconfig 生效
2、 优缺点:
优点: 程序中已包含代码,运行时不再需要静态库。
运行时无需加载库,运行速度更快。
缺点: 静态库中的代码复制到了程序中,使程序会占更多的磁盘和内存空间
静态库升级后,程序需要重新编译链接
添加动态库存在的路径,如:
/home/linux/DC20111/IO/day3/share
在/etc/ld.so.conf.d下 执行:sudo ldconfig 生效
优缺点:
优点: 程序在执行时加载动态库,代码体积小,将一些程序升级变得简单。
不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
缺点:运行时还需要动态库的存在,移植性较差
注意:更新静态库,所有的可执行文件需要重新编译,更新动态库,所有的可执行文件不需要重新进行编译,直接执行。