一、为什么要制作库文件?
(1)现有的库:通过前人写好的完善的库,可以复用的代码,你可以使用但要记得遵守许可协议。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
(2)自己写的库:在做一个项目时,会涉及到多个功能模块,将每个模块通过库的形式进行封装,方便管理与模块化设计。
静态库与动态库的区别?
静态库在程序编译时会被连接到目标代码中,目标程序运行时将不再需要该动态库,移植方便,体积较大,但是浪费空间和资源,因为所有相关的对象文件与牵涉到的库被链接合成一个可执行文件。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此体积较小,可以实现进程间的资源共享,甚至可以真正做到链接载入完全由程序员在程序代码中控制,另外将一些程序的升级变得简单,但是在程序运行时需要动态库存在。
二、库文件的命名规范
在linux下,库文件一般放在/usr/lib /lib下,静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称,动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号
三、如何制作静态库、动态库?
假设我们制作一个计算器的计算库:
代码如下counter.c:
#include <stdio.h>
/*加法*/
float add(float a,float b)
{
return a+b;
}
/*减法*/
float sub(float a,float b)
{
return a-b;
}
/*乘法*/
float multip(float a,float b)
{
return a*b;
}
/*除法*/
float divide(float a,float b)
{
return a/b;
}
静态库制作步骤:
Step 1:gcc -c counter.c -o couter.o
Step 2:ar cqs libcounter.a couter.o
Step 3:cp libcounter.a /usr/lib/
动态库制作步骤:
Step 1:gcc -c counter.c -o couter.o
Step 2:gcc -share -fPIC counter. o -o libcouter.so
Step 3:cp libcounter.so /usr/lib
注:-fPIC:使输出的对象模块是按照可重定位地址方式生成
-shared:指明产生动链接态库
如何使用静态库、动态库?
1.编写库函数头文件:counter.h
#ifdnf _COUNTER_H
#define _COUNTER_H
float add(float a,float b);
float sub(float a,float b);
float multip(float a,float b);
float divide(float a,float b);
#endif
写调用函数:test.c
#include <stdio.h>
#include "counter.h"
int main(void)
{
float result,num1,num2;
num1 = 100;
num2 = 10;
result = add(num1,num2);
printf("num1+num2 = %0.2f \n",result);//+
result = sub(num1,num2);
printf("num1-num2 = %0.2f \n",result);//-
result = sub(num1,num2);
printf("num1xnum2 = %0.2f \n",result);//*
result = sub(num1,num2);
printf("num1/num2 = %0.2f \n",result);// /
return 0;
}
静态库使用:
#gcc test.c -lcounter -o test
#/test
动态库使用:
#gcc test.c -lcounter -o test
#./test
readelf -d test 查看使用的库情况