![ff1067781e02d8b30eda5dc5ea0d916f.png](https://i-blog.csdnimg.cn/blog_migrate/5367977fc862a7663dca7c3d1237602b.jpeg)
图控大叔
构图传递思想
阅读从未如此简单!!!
01
前言
今天分享的内容是:关于Linux下静态库、动态库的制作及使用例程,忘记了的童鞋常回家看看!
02
相关概念
既然今天分享的内容是关于关于Linux下静态库、动态库的制作及使用例程,那么就要先说说函数库、静态库以及动态库等相关概念!
函数库
在我们编程开发的过程中,常常会用到系统的库函数,或者是别人写好的函数,亦或者是我们自己写的函数,那么什么是库函数呢?
库函数(Library function)是把函数放到库里,供别人使用的一种方式。方法是把一些常用到的函数编完放到一个文件里,供不同的人进行调用。调用的时候把它所在的文件名用#include<>加到里面就可以了。一般是放到lib文件里的。
注:该内容来自于百度百科!
看到这里,可以会规范你以前对于库函数的理解及描述,你此时是否会想到,那些看起来很常用的各种库函数,我们常常只是在使用前包含其头文件,以及通过一些命令或者其他手段查看使用规范(如参数、返回值等)。但是对于那些函数的实现过程,却很少知道,那么细想一下,那些函数库只是提供使用接口及相关说明,而不公开具体的实现方法,这样极大的保护了函数开发人员的劳动成果!
上面提到了函数库、库函数,就要提到了另外两个概念:静态库、动态库,请看详细说明!
静态库
静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。
注:该内容来自于百度百科!
Linux环境下静态库的后缀一般为.a
命名格式为:前缀+库名+后缀
如:libadd.a
动态库
相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。
Linux环境下动态库的后缀一般为.so
命名格式为:前缀+库名+后缀+版本号
如:libadd.so.9.0
静态库与动态库的区别
Linux家的伙伴
![21659c224accdf00fb2cb9523bf89dca.png](https://i-blog.csdnimg.cn/blog_migrate/4f727f97675b74d19138731a342eb3b4.jpeg)
静态库
1、被程序静态链接于编译时
2、把静态库函数放到一起编译生成二进制文件(比较大)
![4226a91333c66215bc02013d0b596533.png](https://i-blog.csdnimg.cn/blog_migrate/9a7a01a90692c4d39644470199a42a84.jpeg)
动态库
1、被动态链接于运行时
2、把动态库函数没有放到一起编译生成二进制文件(相对比较小)
3、执行文件的时候是需要去/lib去调用,或者指定目录
03
具体操作
对于Linux环境下,静态库和动态库的制作过程,我以下面C语言简单例子为例。
![d17ee4b4f4e898b1c4d901ef9d5fb191.png](https://i-blog.csdnimg.cn/blog_migrate/4db536dc95f53216d873acaed2771e3d.png)
示例函数
![4bdc4fbf8059966088e4d0398981e724.gif](https://i-blog.csdnimg.cn/blog_migrate/fd777b4274aa6fb69bc62341ea7c7c3d.gif)
#include "add.h"
![4bdc4fbf8059966088e4d0398981e724.gif](https://i-blog.csdnimg.cn/blog_migrate/fd777b4274aa6fb69bc62341ea7c7c3d.gif)
#ifndef __ADD_H__
![4bdc4fbf8059966088e4d0398981e724.gif](https://i-blog.csdnimg.cn/blog_migrate/fd777b4274aa6fb69bc62341ea7c7c3d.gif)
#include "reduce.h"
![4bdc4fbf8059966088e4d0398981e724.gif](https://i-blog.csdnimg.cn/blog_migrate/fd777b4274aa6fb69bc62341ea7c7c3d.gif)
#ifndef __REDUCE_H__
![4bdc4fbf8059966088e4d0398981e724.gif](https://i-blog.csdnimg.cn/blog_migrate/fd777b4274aa6fb69bc62341ea7c7c3d.gif)
#ifndef __MAIN_H__
![4bdc4fbf8059966088e4d0398981e724.gif](https://i-blog.csdnimg.cn/blog_migrate/fd777b4274aa6fb69bc62341ea7c7c3d.gif)
#include "main.h"
这里需要提醒一点,也就是对于头文件包含时所采用的符号
头文件包含的符号
![21659c224accdf00fb2cb9523bf89dca.png](https://i-blog.csdnimg.cn/blog_migrate/4f727f97675b74d19138731a342eb3b4.jpeg)
双引号 ""
从当前目录下去寻找
![4226a91333c66215bc02013d0b596533.png](https://i-blog.csdnimg.cn/blog_migrate/9a7a01a90692c4d39644470199a42a84.jpeg)
尖括号 <>
1、先从系统库函数目录(/lib)去找
2、再从当前目录下去找
3、或者从指定目录下去找
以上文件目录编译生成静态库:
1、把.c文件编译生成.o文件--》两种方法
gcc -c add.c
gcc add.c -c -o add.o
gcc -c reduce.c
gcc reduce.c -c -o reduce.o
2、把.o文件编译生成静态库
ar -rc libadd.a add.o
ar -rc libreduce.a reduce.o
3、静态库的使用:
gcc main.c libadd.a libreduce.a -o project
gcc main.c -o project libadd.a libreduce.a
小编发现步骤太多,每次改一下某个.c文件都需要好几个步骤才能运行,于是在Linux环境下写了个.sh格式的可以执行文件
该.sh文件的创建及权限
touch static_lib.sh
chmod 777 static_lib.sh
该文件内容(仅供参考)
动态库mkdir include;
mkdir static;
cp include/* .;
gcc add.c -o add.o -c;
gcc reduce.c -o reduce.o -c;
ar -rc libadd.a add.o;
ar -rc libreduce.a reduce.o;
rm *.h;
gcc main.c -o project -L ./static *.a -I include;
./project;
编译动态库步骤
1、把.c文件编译生成.so动态库
gcc -fpic -shared add.c -o libadd.so
gcc -fpic -shared reduce.c -o libreduce.so
2、动态库的使用:--》三种编译方式
gcc main.c libadd.so libreduce.so -o project
gcc main.c -o project libadd.so libreduce.so
gcc main.c -o project -L ./lib -ladd -lreduce(必须掌握)
3、执行二进制文件时:
./project
部分命令说明:
-L 告诉编译器去哪里找动态库
-l 告诉编译器要连接的动态库的库名(不需要写前缀、后缀、版本号)
-I 告诉编译器去哪里找头文件(重点)
04
结尾
最近有些忙,一个月里面发推文的次数可能会比之前少了许多,但是还是要发的,还要像写诗一样认真写!