静态库
一、准备工作
新建一个目录,在里面新建include、lib、src三个目录
inculde:保存头文件
lib:保存静态库
src:保存源代码
1、在include目录下新建头文件:head.h
内容:
#ifndef _HEAD_H_
#define _HEAD_H
int add(int a, int b);
#endif
2、在src目录下新建源文件:add.c
内容:
#include "head.h"
int add(int a, int b)
{
int result = a + b;
return result;
}
二、制作静态库
1、利用源文件生成.o的目标文件
gcc add.c -c -I../include // -c :生成.o目标文件;-I ../include:指定头文件在上级目录的include目录下
2、利用目标文件生成静态库,移至lib目录下
上面步骤完成后,静态库的生成已基本完成,要是供给别人使用,只需把头文件和静态库提供,源文件不需要提供给他人,保护了代码实现的细节,只提供代码的接口供别人使用
三、静态库的使用
1、新建main.c文件
内容:
#include <stdio.h>
#include "head.h"
int main(void)
{
int sum = add(1, 2);
printf("sum = %d\n", sum);
return 0;
}
供给别人使用时,别人拿到我们的静态库和头文件,引入我们的头文件,调用我们静态库里面的add的接口,即可完成需求制定
2、生成执行文件
生成的方式有两种:
第一种:gcc main.c lib/libMytest.a -o sum -I include // lib/libMytest.a :指定静态库 ;-o :指定生成执行文件的名称;-I :指令头文件的目录;
第二种:gcc main.c -I include -L lib -l Mytest -o myapp // -L :指定静态库的目录;-l :指令静态库的名字,(静态库全名:lib + 静态库名字 +.a) ;
两种方式都可实现,由上面可以看出结果都是:3
四、静态库优缺点
优点:
- 寻址方便,速度快
- 库被打包到可执行程序中,直接发布可执行程序即可使用
缺点:
- 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
- 如果静态函数库改变了,那么你的程序必须重新编译。
动态库
一、准备工作
准备工作如上;
二、制作动态库
1、生成目标文件:gcc -fPIC -c add.c -I ../include // -fPIC:生成与位置无关的目标文件
位置有关、无关:
静态库是生成与位置有关的目标文件;
动态库是生成与位置无关的目标文件;
静态库把.o文件打包成可执行文件时,会把.o文件包含进去,例:在虚拟地址空间上0-4G(32位的是4G,2的32次方是4G,要是64位就是2的64次方,就不是4G)的地址上,100地址存的是.o文件,每次可执行程序运行,都是从100位置执行.o文件,这里写的对应路径是绝对路径,是与位置有关的目标文件;
动态库把.o文件打包成可执行文件时,不会把.o文件包含进去,只是在相应的位置做个标记,当可执行程序真正运行的时候,才会去加载.o文件;每次运行可执行程序加载进去.o文件可能位置都不一样,里面的路径是相对路径,是与位置无关的目标文件;
2、生成动态库:gcc -shared -o libMytest2.so add.o -I ../include
3、生成可执行文件:
第一种:gcc main.c lib/libMytest2.so -o app -I include;
第二种:gcc main.c -I include -L lib -l Mytest2 -o app2;
由上面可以看到第二种生成的可执行文件运行报错,是找不到对应的.o目标文件;
用ldd app2 ,查看对应的.o文件的映射,libMytest2.so文件not found
4、设置动态库的链接器
第一种:在根目录/lib加入动态库;(可行,但禁止使用)
第二种:LD_LIBRARY_PATH(在默认环境变量之前先查找对应的.o文件)临时导入,关闭终端,重新打开一个终端,设置失效,用于调试使用
- echo $LD_LIBRARY_PATH //打印LD_LIBRARY_PATH的内容
- export LD_LIBRARY_PATH = 绝对路径 //对应.o的绝对路径
第三种:在环境变量里面设置,永久;(不常用)
第四种:动态库的配置文件(常用),/etc/ld.so.conf ;编辑,插入自己的.o文件的绝对路径
更改之后,需要更新:sudo ldconfig -v;
然后再查看app2的文件.o的映射
有了映射关系,并且顺利执行。
三、动态库优缺点
优点:
- 节省内存(共享)
- 易于更新(动态链接)
缺点:
- 延时绑定,速度略慢