1、什么是库?为什么要使用库?
库是一种可执行的二进制文件,是编译好的代码。
使用库可以提高开发效率,加快开发速度。
2、linux下库的种类
linux下库分为两种:静态库与动态库
(1)静态库:静态库在程序编译的时候会被链接到目标代码里面(即:编译程序时,静态库中的函数被拷贝到当前的程序中),所以我们的程序就不再需要该静态库了。因此编译出来的体积就比较大,静态库以lib开头,以.a结尾。
(2)动态库(共享库):动态库在程序编译的时候不会被链接到目标代码里面,而是在程序运行的时候被载入的,所以在程序运行的时候就需要动态库。因此编译出来的体积就比较小。动态库以 lib 开头,以.so 结尾。
思考:这两种库分别适用于什么情况呢?
如果现在有10个程序,这10个程序都用到了相同的库,此时用动态库会比较合适。因为动态库在程序编译的时候没有被链接到目标代码里面,这10个程序都用到一个库,若用动态库的话,这10个程序就不用链接10次该过程,只需要在环境中有这个库,这10个程序就可以运行。 但是如果用静态库的话,这10个程序每一个程序都需要进行一次链接,操作步骤会变得繁琐,同时编译出来的体积会相对较大。
何时使用静态库呢?
如果程序需要移植一下,此时用静态库是很好的,因为静态库在编译的时候会被链接到目标代码里面,此时在环境中就不需要该静态库了,在进行移植操作的时候就会比较便利。
注释:动态库与静态库最大的区别在于“库的加载时间不同。”
3、静态库的制作与使用
(1)静态库的制作步骤
a、编写或准备库的源代码
b、将源码.c 文件编译生成.o 文件(.o文件是目标文件,直接使用“-c”参数即可)
c、使用ar命令创建静态库
d、测试库文件
(2)静态库制作与使用示例
a、编写或准备库的源代码
#include <stdio.h>
//声明一下自己制作的静态库函数
//该库提供的功能是打印This is mylib!
void mylib(void);
void mylib(void){
printf("This is mylib!\n");
//无参数,无返回值。仅仅让它打印“This is mylib!”
}
b、将源码.c 文件编译生成.o 文件
c、使用ar命令创建静态库
此时需要加入两个参数“c”“r”,“c”代表的是创建,“r”代表的是覆盖
静态库的文件名是以lib开头,.a结尾,故整个静态库的库文件名为lib+库名+.a=libstatic.a
特别需要注意的地方是:libstatic.a为库文件名,而static是库名
d、测试库文件
编写测试代码如下:
#include <stdio.h>
void mylib(void);
int main(void)
{
mylib();
return 0;
}
测试代码编写完成之后,在ubuntu界面编译该测试代码。但是此时需要指定一下链接库与库所在的路径,用小写的“l”来指定链接库,小写的“l”后面跟库名;用大写“L”来指定路径,由于在当前路径下,所以用“.”来代替当前路径即可。 编译完成之后,执行生成的可执行文件a.out,得到测试结果为显示:This is mylib!
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/175d630655ee5835cb46921debf6e275.png)
注意事项:
如果程序代码用到了库文件里面的函数,那么在编译的时候需要链接库。系统默认会在/lib或者/usr/lib去找库文件。或者在编译的时候使用我们自己指定的路径,比如上述示例中的:
gcc test.c -lstatic -L .
-l:指定静态库的库名
-L :指定静态库的查找位置
-L . :表示在当前目录下去查找
4、动态库的制作与使用
(1)动态库的制作步骤
a、编写或准备库的源代码
b、将源码.c 文件编译生成.o 文件
c、使用 gcc 命令创建动态库
d、测试库文件
(2)动态库制作、使用示例
此处仍然使用静态库之所与使用示例中的“库”的源码以及测试代码。静态库与动态库在制作过程中的最主要区别是创建时候的区别,创建动态库时使用的命令为gcc
a、编写或准备库的源代码(与上面静态库的源代码相同)
b、将源码.c 文件编译生成.o 文件
在使用gcc命令创建动态库的时候,有个参数是“-fpic”,该参数的意思是:“产生与位置无关的代码(Position—Independent Code)”,因为一个动态库可以被多个目标代码加载,而每个目标代码加载的地址是不一样的,所以要加上“-fpic”参数。c、使用 gcc 命令创建动态库
gcc -shared -o libdynamic.so dynamic.o
其中“-shared”是指生成动态库
动态库库文件名(libdynamic.so) = lib+库名(dynamic)+.so
d、测试库文件
如果像编译静态库的测试文件时候的那种编译,会报错,如下图所示。
为什么会出现这情况呢?因为静态库在编译的时候是链接到目标代码里面的,在运行的时候就不需要静态库了,但是动态库是在运行的时候才载入的,所以环境中需要这个库。 但是现在还存在一个问题,在当前目录下是有“libdynamic.so”这个文件的,为什么还会执行失败呢?因为系统默认会在/lib或者/usr/lib去找库文件,如果在这两个地方找不到该文件,就会报错。
解决该问题有三种办法:
办法一:
将生成的动态库拷贝到/lib或者/usr/lib里面去,因为系统会默认去这两个地方找,但是自己编写的动态库时不被建议将其拷贝到这两个路径下的建议使用其他两种办法
办法二:
把自己制作好的动态库所在的路径加到环境变量里面去,比如我们动态库所在的路径为/home/samba/ku,就可以这样添加,但是这种方法只在当前设置的窗口有效。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:+动态库所在的路径
root@ubuntu:/home/samba/ku# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/samba/ku
root@ubuntu:/home/samba/ku# ./a.out
This is mylib!
办法三:
修改 ubuntu 下的配置文件/etc/ld.so.conf,在这个配置文件里面加入动态库所在的位置,然后使用命令 ldconfig 更新目录。