关于Linux静态库和动态库的分析
1.什么是库 2.库的种类 二者的不同点在于代码被加载的时刻不同。 3.库存在的意义 4.库文件是怎样产生的在linux下 5.库文件是怎样命名的,有没有什么规范 6.怎样知道一个可运行程序依赖哪些库 7.可运行程序在运行的时候怎样定位共享库文件 8.在新安装一个库之后怎样让系统可以找到他 我们通常把一些公用函数制作成函数库,供其他程序使用。 函数库分为静态库和动态库两种。 静态库在程序编译时会被连接到目标代码中,程序执行时将不再须要该静态库。动态库在程序编译时并不会被连接到目标代码中。而是在程序执行是才被加载,因此在程序执行时还须要动态库存在。 本文主要通过举例来说明在Linux 步:编辑得到举例的程序--hello.h、hello.c和main.c; hello.h(见程序1)为该函数库的头文件。 hello.c(见程序2)是函数库的源程序。当中包括公用函数hello。该函数将在屏幕上输出"Hello main.c(见程序3)为測试库文件的主程序,在主程序中调用了公用函数hello。 程序1: hello.h #ifndef HELLO_H #define HELLO_H void hello(const char *name); #endif //HELLO_H 程序2: hello.c #include <stdio.h> void hello(const char *name) { printf("Hello %s!\n", name); } #include "hello.h" int main() { hello("everyone"); return 0; } 步:将hello.c编译成.o文件; 不管静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。 在系统提示符下键入下面命令得到hello.o文件。 # gcc -c hello.c 我们执行ls命令看看是否生存了hello.o文件。 # ls hello.c hello.h hello.o main.c 在ls命令结果中,我们看到了hello.o文件。本步操作完毕。 以下我们先来看看怎样创建静态库,以及使用它。 步:由.o文件创建静态库。 静态库文件名称的命名规范是以lib为前缀。紧接着跟静态库名。扩展名为.a。比如:我们将创建的静态库名为myhello,则静态库文件名称就是libmyhello.a。 在创建和使用静态库时,须要注意这点。创建静态库用ar命令。 在系统提示符下键入下面命令将创建静态库文件libmyhello.a。 # ar cr libmyhello.a hello.o 我们相同执行ls命令查看结果:# ls ls命令结果中有libmyhello.a。 hello.c hello.h hello.o libmyhello.a main.c 步:在程序中使用静态库。 静态库制作完了,怎样使用它内部的函数呢?仅仅须要在使用到这些公用函数的源程序中包括这些公用函数的原型声明。然后在用gcc命令生成目标文件时指明静态库名。gcc将会从静态库中将公用函数连接到目标文件里。 注意。gcc会在静态库名前加上前缀lib。然后追加扩展名.a得到的静态库文件名称来查找静态库文件。 在程序3:main.c中。我们包括了静态库的头文件hello.h,然后在主程序main中直接调用公用函数hello。以下先生成目标程序hello。然后执行hello程序看看结果怎样。 # gcc -o hello main.c -L. -lmyhello # ./hello Hello everyone! 我们删除静态库文件试试公用函数hello是否真的连接到目标文件 hello中了。 # rm libmyhello.a rm: remove regular file `libmyhello.a'? y # ./hello Hello everyone! 程序照常执行,静态库中的公用函数已经连接到目标文件里了。 我们继续看看怎样在Linux中创建动态库。 我们还是从.o文件開始。 步:由.o文件创建动态库文件。 动态库文件名称命名规范和静态库文件名称命名规范类似。也是在动态库名添加前缀lib,但其文件扩展名为.so。 比如:我们将创建的动态库名为myhello,则动态库文件名称就是libmyhello.so。 用gcc来创建动态库。 在系统提示符下键入下面命令得到动态库文件libmyhello.so。 # gcc -shared -fPIC -o libmyhello.so hello.o 我们照样使用ls命令看看动态库文件是否生成。# ls hello.c hello.h hello.o libmyhello.so main.c 步:在程序中使用动态库; 在程序中使用动态库和使用静态库全然一样,也是在使用到这些公用函数的源程序中包括这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明动态库名进行编译。我们先执行gcc命令生成目标文件,再执行它看看结果。 # gcc -o hello main.c -L. –lmyhello $gcc–o app main.c /home/test/program/ibmyLib.so $gcc -o app2 main.c $PWD/libmyhelloso.so # ./hello ./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory # 哦!出错了。快看看错误提示。原来是找不到动态库文件libmyhello.so。 程序在执行时,会在/usr/lib和/lib等文件夹中查找须要的动态库文件。若找到,则加载动态库。否则将提示类似上述错误而终止程序执行。我们将文件libmyhello.so拷贝到文件夹/usr/lib中,再试试。 # mv libmyhello.so /usr/lib # ./hello ./hello: error while loading shared libraries: /usr/lib/libhello.so: cannot restore segment prot after reloc: Permission denied # chcon -t texrel_shlib_t /usr/lib/libhello.so # ./hello Hello everyone! # 成功了。这也进一步说明了动态库在程序执行时是须要的。 |