一、库是什么? 简介:
假如,你有一个庞大的工程,代码量达到数百兆甚至是数G,你经常会遇到好多重复或常用的地方。每次使用到这些地方时如果都重新写一份基本相同的代码,这当然可以,不过这样会大大地降低工作效率,而且影响代码的可读性。更不好的是日后的修改工作会使你变得非常的繁琐,这样很不利于后期的维护。如果把这些相同的功能代码分别以模块的形式存放起来,把他们编译成库,使用时直接调用他们的库,这样直接使用起来非常的方便,更有利于代码的维护和升级。
库的概念:
库是由源代码编译出来的,是对一组源文件编译出来的中间文件(可以看我上一篇文章,在代码经过汇编过程后)。使用库可以做到不开放源代码,同时令其他单元可以调用到的效果,实现良好的接口封装。
其实,现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。比如我们常使用的printf函数,就是c标准库提供的函数。我们在使用时只需要包含相应的头文件就可以使用(非静态编译还要有相应的库文件)。而不用关心printf函数具体是如何实现的,这样就大大提高了程序员编写代码的效率。
二、库的分类
库大体上可以分为两类:静态库和动态库。在windows中静态库是以 .lib 为后缀的文件,共享库是以 .dll 为后缀的文件。在linux中静态库是以 .a 为后缀的文件,动态库是以 .so为后缀的文件。
创建动态库:
//func.c
int max(int a ,int b){
return (a>b)?a:b;

}
生成链接库文件,会生成一个libfunc.so
gcc -fPIC -shared -o libfunc.so func.c
PIC:产生与位置无关代码,PIC(Position-Independent Code),代码中没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置linux vi 命令,都可以正确的执行
-shared:生成动态链接库
调用动态库linux是什么,编译,执行: 创建 test.c文件
1. vim test.c
2. Shift + i
3. 编写代码
4. Esc Shift + :
5. wq
编写代码
#include
void main(){

printf("%dn",max(23,5));
}
编译(包含链接库),生成可执行文件test.out
gcc test.c -o test.out -L. -lfunc
执行
./test.out
答案毫无疑问,报错!
解决报错
因为系统链接库列表中没有找到这个链接库,需要将这个链接库注册到系统
可以这么理解linux创建文件,因为编译生成执行文件的时候,只是使用了libfunc.so的定义,并没有把函数体整个包含进来,运行的时候用函数定义去动态查找完整的方法linux创建文件,那完整的方法怎么找?
1.使用系统默认链接库目录,这种方式需要把libfunc.so放入系统目录下:/lib,/usr/lib等
2.指明链接库目录目录,这种方式需要把libfunc.so目录注册到系统系统目录列表里,将libfunc.so所在目录写入文件etc/ld.so.conf,保存,执行:ldconfig,让系统添加库文件夹下的链接库文件
上面这时候再执行:./test.out,就能获得结果了
代码优化
上面代码虽然能正确执行了,但是有个问题,如果给你一个so文件,你能使用吗?
打开文件是乱码,里面有什么方法大家都不知道,所以我们要定义一个规范,能让使用者清晰的知道链接库中包含了哪些方法,所以需要建立一个头文件,说明func链接库里面包含哪些方法
//test.c
#include
#include"func.h"
void main(){
printf("%dn",max(23,5));
}
这样就优化了代码的可读性