1. 概念
当使用别人的函数时除了包含头文件以外还要有库
头文件:函数声明、结构体等类型定义、头文件、宏定义
库:就是把一些常用函数的目标文件打包在一起,提供相应函数的接口,便于程序员使用;本质 上来说库是一种可执行代码的二进制形式
由于windows和linux的本质不同,因此二者库的二进制是不兼容的
2. 分类:
静态库和共享库(动态库)
3. 区别:
1.静态库在程序编译时会被连接到目标代码中。
优点:程序运行时将不再需要该静态库;运行时无需加载库,运行速度更快
缺点:静态库中的代码复制到了程序中,因此体积较大;静态库升级后,程序需要重新编译链接
2.动态库是在程序运行时才被载入代码中。
优点:程序在执行时加载动态库,代码体积小;将一些程序升级变得简单;不同的应用程序如果 调用相同的库,那么在内存里只需要有一份该共享库的实例。
缺点:运行时还需要动态库的存在,移植性较差
4. 静态库的制作:
1-将源文件编译生成目标文件
gcc -c add.c -o add.o
2-创建静态库用ar命令,它将很多.o转换成.a
ar crs libmyadd.a add.o
静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a
3测试:
3-使用静态链接库
gcc main.c -L. -lmyadd
-L. :指的是库的路径
4-执行./a.out
5. 动态库
1-我们用gcc来创建共享库
gcc -fPIC -c hello.c -o hello.o
-fPIC 创建与地址无关的编译程序
gcc -shared -o libmyhello.so hello.o
2-测试动态库使用
gcc main.c -L. -lmyhello
可以正常编译通过,但是运行时报错./a.out: error while loading shared libraries: libmyadd.so: cannot open shared object file: No such file or directory
原因:当加载动态库时,系统会默认从/lib或/usr/lib路径下查找
解决方法(有三种):
(1)把库拷贝到/usr/lib和/lib目录下。(此方法编译时不需要指定库的路径)
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
(终端关闭,环境变量就没在了)、
(3) 添加/etc/ld.so.conf.d/*.conf文件
把库所在的路径加到文件末尾,并执行ldconfig刷新
sudo vi xx.conf
添加动态库存在的路径,如:
/home/hq/teach/22061/day3/dynamiclib