一、库是什么?
本质上来说,库时一种可执行代码的二进制形式,可以被操作系统载入内存执行。我们通常将一些通用函数写成函数库,所以库是写好的,现有的,成熟的,可以复用的代码,可以使用但要必须得遵守许可协议。在我们现实开发过程中,不可能每一份代码都从头编写,当我们拥有库时,我们就可以直接将我们所需要的文件链接到我们的程序中。可以为我们节省大量的时间,提高开发效率。
二、静态库与动态库的生成
1.静态库的生成
静态库在linux中的形式:lib库名.a;windows中与它相同。
链接过程:在链接生成可执行文件的时候,静态库会把它的可执行代码都整合到可执行文件当中去,所以静态库编译的可执行文件占的空间更加大,并且静态库发生更新改变,你的程序必须重新编译。
静态库生成要先生成目标(.o)文件,代码如下:
iot23@nbraspberrypi:~/dengyonghao $ gcc -c test.c
iot23@nbraspberrypi:~/dengyonghao $ gcc -c test2.c
iot23@nbraspberrypi:~/dengyonghao $ ls
Makefile client server test.c test.o test2.c test2.o
然后再进行生成静态库,代码如下:
iot23@nbraspberrypi:~/dengyonghao $ ar -rcs libtest.a test.o test2.o
iot23@nbraspberrypi:~/dengyonghao $ ls
Makefile client libtest.a server test.c test.o test2.c test2.o
可见我们成功生成了静态库libtest.a。
2.动态库的生成
动态库的命名方式与静态库类似,前缀相同为“lib”,linux下后缀名为“.so(shared object)”即lib库名.so;而windows下后缀名为“.dll(dynamic link library)”即lib库名.dll。
链接过程:静态库会把代码段编译到可执行文件当中去,而动态库不会,代码段都在动态库中,在运行时操作系统才会把动态库加载到内存的相应路径里去,它是动态加载的所以叫动态库。动态库的改变并不影响你的程序,所以动态函数库升级比较方便。
动态库生成代码如下:
iot23@nbraspberrypi:~/dengyonghao/ds18-b20_get_temperature1 $ gcc -shared -fPIC -o libtest.so test.c test2.c
iot23@nbraspberrypi:~/dengyonghao/ds18-b20_get_temperature1 $ ls
Makefile client libtest.a libtest.so server test.c test.o test2.c test2.o
可见我们成功生成了动态库libtest.so。
三、三个编译条件
系统只会去系统默认的地方找对应库和文件,如果我们没有管理员权限或者没有把这些添加到默认路径当中去,那么系统当然找不到,所以这就需要我们再次使用“仙人指路”技能,告诉系统要去哪个地方找对应的库和文件。
1.指定头文件路径
当我们直接用gcc编译的时候有可能会出现以下错误:
这是因为系统找不到对应头文件,我们可以通过(-I大写i)指定头文件路径:
2.指定库
指定了头文件路径后还有可能报如下错误:
这是因为系统不知道对应库,我们可以通过(-l小写L)指定库:
用-l加上库名指定,库名就是在库文件减去lib与.so或.a后的名字。
3.指定库路径
指定了库后还有可能报如下错误:
这是因为系统不知道到哪里去找对应的库,我们可以通过(-L)指定库路径:
最后即可编译成功,生成a.out可执行文件。
四、运行调用
我们知道如果我们直接用a.out来执行可执行文件那么会报以下错误:
直接用a.out执行它找不到这个命令所以给我们抛出此错误,所以我们应该去修改环境变量PATH,通过如下命令可以看到环境变量:
echo &PATH
然后我们可以修改环境变量:
export PATH=$PATH:/home/...
冒号后必须要是自己的命令的绝对路径,然后就可以通过直接a.out执行,不需要./a.out
在运行时:静态库的可执行代码已经编译到了可执行文件中去,而动态库并没有,所以就会出现以下情况:
当然这是因为找到了指令还没找到动态库,动态库也有一个环境变量,修改方法如下:
export LD_LIBRARY_PATH=/home/...
冒号后是自己的动态库的绝对路径,修改后即可正常运行了。
对于两个库都有时,运行时系统会默认优先使用动态库。
五、总结
本章讲解了动态库与静态库技术,从什么是库讲解起,然后讲解了如何生成动态库与静态库,并解决了编译时的问题,最后讲解了如何运行通过动态库或静态库编译好的可执行文件。
别忘了点赞 收藏 呀!