静态库和动态库

目录

1.静态库

1.前期工作,编写静态库

2.如何编译main.c,导入静态库

2.动态库

1.准备工作,编写动态库

2.如何将动态库加载到main.c文件中

1.拷贝到系统默认的库路径/lib64或则/usr/lib64/

2.在系统默认的库路径/lib64/或者/usr/lib64/下建立软连接

3.将自己的库所在的路径,添加到系统的环境变量LD_LIBRARY_PATH中

4./etc/ld.so.conf.d/的路径下建立自己的动态库路径的配置文件,然后重新ldconfig即可

3.如何共同加载动态库和静态库

4.总结

1.静态库

1.前期工作,编写静态库

我们要链接两个.h文件到一个静态库中:

静态库和动态库_第1张图片

静态库和动态库_第2张图片

然后我们就可以make;make output;

之后就是创建main.c,且把lib这个文件夹导入进去:

静态库和动态库_第3张图片

2.如何编译main.c,导入静态库

首先简单的gcc命令显示的是找不到库的头文件,最直接的办法就是将头文件导入当前目录下(这是我们当前的办法),还有就是告诉编译器,我们的路径在哪里:-I

静态库和动态库_第4张图片

但是编译现在找到头文件了,但是依旧无法编译,那哪出错了呢?很简单,报错的是函数未定义,就是声明但是找不到定义,相当于就是链接的时候出错了!怎么验证?很简单,我们现在是可以编译.o文件的:
静态库和动态库_第5张图片

所以就是gcc找不到静态库的位置:(-L)

但是依旧不行,其实是我们没有告诉编译器要编译哪个静态库,因为main.c中有#include告诉他要找哪个头文件,但是没有告诉他要编译哪个库:所以-l命令(去掉lib前缀和.a后缀,且不要加空格):

但是,我们在编写正常程序时,哪里需要这么麻烦呢?其实如果我们把.h和.a放到系统路径下,我就可以只加-l告诉编译器,我们要哪个.a文件就行了:
静态库和动态库_第6张图片

2.动态库

1.准备工作,编写动态库

文件和上面两个.h是一样的,更改的是Makefile文件内容:
静态库和动态库_第7张图片

进行和上面静态库一样的操作:

静态库和动态库_第8张图片

2.如何将动态库加载到main.c文件中

如果我们按照静态库的方法编译是会报错的,细心的人看到我列的标题就会发现,我说静态库是导入,而动态库是加载:

静态库和动态库_第9张图片

我们已经告诉编译器,要找到libmytest.so的动态库了,但是为什么还不行呢?因为我们还没有告诉加载器,我们要加载哪一个库!

所以,这边我们可以先跳到总结那边看,会更好一点!

解决加载找不到的动态库方法:

1.拷贝到系统默认的库路径/lib64或则/usr/lib64/

2.在系统默认的库路径/lib64/或者/usr/lib64/下建立软连接

静态库和动态库_第10张图片

3.将自己的库所在的路径,添加到系统的环境变量LD_LIBRARY_PATH中

静态库和动态库_第11张图片

也可以这样验证一下,其他方法一样:

静态库和动态库_第12张图片

4./etc/ld.so.conf.d/的路径下建立自己的动态库路径的配置文件,然后重新ldconfig即可

静态库和动态库_第13张图片

3.如何共同加载动态库和静态库

就是Makefile中的all:

静态库和动态库_第14张图片

4.总结

通过上面的讲解,我们知道一件事:

所以,如果很多个进程如果要使用同一个静态库,那么内存中会同时存在很多个相同的数据与代码,因此会很浪费空间,而动态库则可以直接共享,只加载一遍到内存中就可以了!这就是静态库和动态库的区别!

想看动态库在内存中如何实现加载共享的,可以看我下一篇文章:
动态库是怎么被加载的?-CSDN博客

你可能感兴趣的:(服务器,linux,运维)