Linux下静态库与动态库

来源:互联网 发布:蚂蚁活多久 知乎 编辑:程序博客网 时间:2024/05/16 10:43

静态库:在可执行程序之前就已经加载到可执行程序的代码中,是可执行程序的一部分。一般以.a作为静态库文件的后缀名,使用ar(archiver)命令可以创建静态库。

优点:不会因为库文件的丢失而出现运行失败  缺点:维护和更新困难

静态库:储存的是目标文件打包后形成的一个库文件

生成步骤:

1.编译源文件1 源文件2 ...

2.b编译成目标文件1 目标文件2...

3.打包成静态库 以lib开头.a结尾 

4. 链接:gcc/g++ main.c -L(oadFilePath).(没有指定目录回去环境变量下去寻找) -l(ib)库文件名.a -o 输出文件

以冒泡排序为例

bubble_sort.cpp文件

[cpp] view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4.   
  5.   
  6. void bubble_sort(int *buf,int len)  
  7. {  
  8.     int i,j;  
  9.     for(i = 1;i<len;i++)  
  10.     {  
  11.         for(j = len-1;j>=i;j--)  
  12.         {  
  13.             if(buf[j-1]>buf[j])  
  14.             {  
  15.                 buf[j] ^= buf[j-1];  
  16.                 buf[j-1]^= buf[j];  
  17.                 buf[j] ^= buf[j-1];  
  18.             }  
  19.         }  
  20.     }  
  21. }  
  22.   
  23.   
  24. void show(int *buf,int len)  
  25. {  
  26.     for(int i = 0;i<len;i++)  
  27.         cout<<buf[i];  
  28.     cout<<endl;  
  29. }     
bubble_sort.h文件

[cpp] view plain copy
  1. extern void bubble_sort(int *buf,int len);  
  2. extern void show(int *buf,int len);  
main.cpp文件

[cpp] view plain copy
  1. #include "bubble_sort.h"  
  2.   
  3.   
  4. int main()  
  5. {  
  6.     int buf[6] = {1,4,3,6,5,2};  
  7.     bubble_sort(buf,6);  
  8.     show(buf,6);  
  9.   
  10.     return 0;  
  11. }  
跟随下面这些步骤可以生成静态库,以及如何链接静态库



动态库

编译阶段并不是可执行程序的一部分,而是在运行阶段需要此动态库时才进行导入。

动态库生成步骤:

1.编写源文件

2.生成可执行的库文件 gcc/g++ -fPIC -shared -o lib*.so

3.加载库文件(分为两种 共享加载 动态加载)

共享加载 编译时指定动态库

我们还是以冒泡排序为例子


我们发现程序在运行阶段无法正确加载共享库,这是为什么呢?首先我们可以肯定,这肯定是共享库(在运行阶段产生错误),这是要给大家列出几个命令

ldd ->查找可执行文件的库的依赖关系  还有下面用到的nm->列出符号名的关系,我们使用ldd查看我们的可执行文件,看一下库文件的依赖关系。


我们发现libsort库并没有像其他库一样指向某个地方,原因就是因为在运行阶段我们仅仅只是把符号表导入了进来.

这时候又涉及到一个新的知识点,每个进程都有自己的LD_LIBRARY_PATH(在需要库文件时,系统会去该路径下去寻找库文件如果没有,就会出现错误),我们试着输出该环境变量的值


我们发现该环境变量为空.这是我们设置其值。看能否成功


程序正常运行,还有一种方式就是将,libsort.so文件放入到usr/lib/下程序同样可正确运行

静态库拓展

共享库一般有会有多个名字

real name  (库名.so.主版本号.次版本号)  so name(库名.so.主版本号) link name(库名.so)

我们为了在实际开发过程中同时会设置相关的名字


动态加载

何为动态加载,就是指在需要的地方才加载相关的库函数
还是以冒泡排序为例
这时main函数需要改变

[cpp] view plain copy
  1. #include "bubble_sort.h"  
  2. #include <iostream>  
  3. #include <dlfcn.h>  
  4. using namespace std;  
  5.   
  6. #define LIB_PATH "./libsort.so"  
  7. typedef void (*pFun)(int*,int);  
  8.   
  9.   
  10. bool autoload(const char *filename,const char *symbol,int *buf,int len)  
  11. {  
  12.     char* error =NULL;  
  13.     void* handle = dlopen(filename,RTLD_LAZY);  
  14.     if(NULL != (error=dlerror()))  
  15.     {  
  16.         cerr<<error;  
  17.         return false;  
  18.     }  
  19.       
  20.     pFun p;  
  21.     p =(void(*)(int*,int))dlsym(handle,symbol);  
  22.     if(NULL != (error = dlerror()))  
  23.     {  
  24.         cerr<<error;  
  25.         return false;  
  26.     }  
  27.   
  28.     p(buf,len);  
  29.     cout<<symbol<<endl;  
  30.       
  31.     dlclose(handle);  
  32.     return true;  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     int buf[6] = {1,4,3,6,5,2};  
  38.     autoload(LIB_PATH,"bubble_sort",buf,6);  
  39.     autoload(LIB_PATH,"show",buf,6);  
  40.   
  41.     return 0;  
  42. }