1.库的定义
当使用别人的函数时除了包含头文件以外还要有库
Linux系统存储库的位置一般在/lib或/usr/lib
库文件:通俗讲将用户写好的程序打包形成一个整体;当其他用户或其他模块使用时,只要有这个库文件就可以,不需要源代码。也可以理解为一组预先编译好的方法集合。
本质上来说库就是一种可执行的二进制形式
由于Windows和Linux的本质不同,因此二者库的二进制是不兼容的
Linux:.so .a Windows:.dll
lib:库文件
include:头文件
2.库的分类
动态库、静态库,本质区别是代码载入时刻不同
2.1静态库
静态库是在程序编译时会被复制到目标代码中,以.a结尾
优点:程序运行时将不再需要该静态库;运行时无需加载库,运行速度更快
缺点:静态库中的代码复制到了程序中,因此体积较大;静态库升级后,程序需要重新编译链接
2.2动态库
动态库是在程序运行时才会被载入到代码中。也叫共享库,以.so结尾
优点:程序在执行时加载动态库,代码体积小;程序升级更简单;
不同应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实列。
缺点:运行时还需要动态库的存在,移植性较差
3.库的制作
3.1静态库的制作
1-将原文件编译成目标文件
gcc -c xx.c -o xx.o
2-创建静态库用ar命令,它将很多.o文件转换成.a
ar crs libxxx.a xxx.o xxx.o ....
静态库文件名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a
3-测试使用静态库
gcc xx.c -L. -l库名 //-L指定库的路径 -l指定库名
3.2动态库的制作
1.我们用gcc来创建共享库
gcc -fPIC -c xx.c -o xx.o
-fPIC 创建与地址无关的编译程序
gcc -shared -o libxxx.so xx.o xx.o ....
2.测试使用动态库:
gcc xx.c -L. -l指定库名
可以正常编译通过,但是运行时报错./a.out: error while loading shared libraries: libmyadd.so: cannot open shared object file: No such file or directory
原因:当加载动态库时,系统会默认从/lib或/usr/lib路径下查找库文件,所以不用加-L指定路径了,直接gcc main.c -lmydynamic就可以了。
解决方法
1)把库拷贝到/usr/lib和/lib目录下。(此方法编译时不需要指定库的路径)
补充:
-L路径:指定库的路径
-l库名:指定链接的库名
-I(大写i)路径:指定头文件的路径 默认查找的路径/usr/include
<>代表从系统路径下查找
“”代表从当前路径下查找如果没有再去系统路径下查找
ldd 可执行文件名:查看链接的动态库
补充:
同名的静态库和动态库:默认优先使用动态库,如果想使用静态库,需要在后面加-static,这是内核规定的。
如果链接没有lib前缀库文件,可以直接使用-指定的全名无需加载选项。
3.3总结静态库和动态库
静态库:编译阶段,以.a结尾,执行速度快,体积大,移植性好,升级麻烦。
动态库:运行阶段,以.so结尾,执行速度慢,体积小,移植性差,升级简单。