库:是一种软件组织技术,库里面封装函数和数据,提供给用户数据使用,每个人的程 序,不可能都从零开始,都是依赖一些基础的库函数,尽量不要重复别人已经做 过 的事情,也就是充分利用别人的劳动成果站在巨人的肩膀,就本人对“库的设计”理 解有两点作用,一是提供一种共享的思想,二是对别人的劳动成果进行知识产权保 护。
Linux下通常把库放在/usr/lib 或者/lib ,64位机器放在/usr/lib64或者/lib64,。
库的分类:
库分为静态库和动态库,两者的不同点在于代码被载入的时刻不同。
静态库 :一般格式是lib***.a由ar –cr lib***.a ***.o,***.o, ...创建生成不可执行静态库文件。
动态库: 是lib***.so由gcc –shared–o lib***.so ***.o,***.o, . . .编译生成可执行文件 lib***.so可执行动态库文件。其中***是自己定义库的名称。
静态库在于编译过程中,已经封装好了众多.o 的目标代码,并且已经被载入可执行程 序。静态库的优点在于所有函数在编译时候都被整合成静态库函数copy到应用程序中了,当多个程序同时引用一个静态库函数时,内存中将调用函数的多个副本,这样的优点是节省编译时间,这也正是他的缺点,如果静态库函数某一功能要改变了,你的程序必须重新编译,并且静态库体积较大。
动态库又称共享库,动态函数库在编译时候并没有被编译进目标代码,当你程序执行相关函数是才调用该动态库,所以动态库的体积较小,达到一种共享的思想,也就是说,由于动态库没有被整合进你的程序,所以执行当你执行该程序时候,才去申请调用动态库函数,并且动态库函数可以在程序运行期间释放掉动态库所占的内存,腾出空降供其他函数使用。
一、静态库的创建
1.在头文件中声明所要输出的静态库所要导出的函数。
2.在源函数在实现静态库所要导出的函数。
3.在源文件中生成.o的目标文件(只编译不链接的二进制文件)。
注意: -c 生成.o的目标文件必须加上,否则编译失败,此时源代码已经被保护起来。
4.编译生成静态库
注意:ar –cr lib****.a ****.o
-c代表create创建一个库。
-r代表replace如库中已有该名称的静态库文件取而代之。
-s代表无论ar命令是否修改了库函数,都强制生成库符号表 –d从库中删除某成员(目标代码)。
-a 代表从库中添加某成员。
5. 测试静态库
使用text.c的函数,编译生成可执行文件时,必须链接链接静态库,此时静态库可以是当前目录下,也可以是/usr/lib或者/lib(前提是lib***.a的静态库函数copy到该目录下)编译成功生成test的可执行文件,而此时删除掉静态库文件test依然可以执行(静态库文件在编译时候已经把目标代码整合进程序了)。
./L 表示静态函数库的位置,后面有个.表示当前目录
二、动态库的创建
1.在头文件声明所输出的动态库所要导出的函数。
2.在源文件中实现动态库所要导出的函数。
3.编译源文件生成 .O的目标文件(只编译不链接的 二进制代码)。
-fPIC或者-fpic:fPIC作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code)则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
-fpic为了节约内存,在GOT里面预留了"短"长度。
而-fPIC则采用了更大的跳转项。
4.编译生成动态库
或者目标文件和生成文件一步完成。
由此可见动态库函数是一个可执行文件,由gcc编译生成,区别于静态库函数不可执行文件,静态库由ar –cr创建。
5。测试动态库
Linux下有两种方法调用动态链接库一种是类似静态库通过gcc命令调用,另一种是调用系统函数来使用动态链接库。
通过gcc命令调用,必须链接动态库当前路径,和链接静态库类似。
另外一种方法是调用动态库系统函数dlopen(),dlsym().,dlclose(),dlerror(),有兴趣可以下去研究研究。。。
如果把当前目录下的动态库文件删除就不能执行test文件了,要重新执行test文件就必须重新编译 链接库函数。