1. 静态函数库

这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

2. 动态函数库

这类库的名字一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。 
linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。

编译静态库和动态库 :

无论是静态库还是动态库 ,都是由.o文件组成。因此我们可以先编译出.o文件 。
下面提供两个小程序 :
sum.h

#ifndef SUM_H_
#define SUM_H_ int add (int ,int ) ; #endif

sum.cpp 

#include <iostream>
#include "auth.h" int add (int x ,int y )
{
int sum = x + y ;
return sum ;
}
#include "sum.h"
#include<iostream>
int main()
{
int k = add(8,10);
std::cout<<"k= "<< k<<std::endl;
return 0 ;
}

linux32位系统下 :

首先编译.o文件:

g++ -c sum.cpp    ------>生成.o文件
  
编译.so 文件 :
g++ -shared -fPIC -o libsum.so sum.o       ------>生成libsum.so文件

编译.a 文件 :
ar rcs libsum.a sum.o   - ----> 生成libsum.a 文件 

编译测试文件并测试 :
g++ -c test.cpp 
g++ -o test test.o -lauth -L./ 
ok,测试结果显示k = 18 ;

然而 在linux64位的系统中,这个问题就出来了 。
如果依然按照上面的命令进行编译 ,会出现以下错误 :
      /usr/bin/ld: sum.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
auth.o: could not read symbols: Bad value。
碰到这个错误 ,你可以去检查下,对应的文件在编译的时候是不是用了-fPIC这个参数哦 。

 -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

在生成.o文件的时候 加上参数 -fPIC ,这个错误就可以搞定了 ,在编译动态库时,必须指定这个参数 ,主要是因为代码的重定向的问题 。如果没有这个参数 ,编译的代码加载的时候不能够重定向。
 g++ -fPIC -c sum.cpp 

那么,如果我希望指定执行文件链接静态库怎么办呢 ??
默认情况下,如果在某个目录下.so 和.a 同时存在的时 ,gcc会优先选择.so 。
我们一般通过 -I引入包含文件 ,-L引入库目录 ,-l指定依赖的库文件。当在静态库和动态库同时存在时,gcc选择.so ,如果你在能够将.
so和.a分开的情况下 ,使用-lname (name为lib的名字)来指定库文件(无论静态库还是动态库都可以),如果静态库和动态库在同一目录下 ,可以使用 path/libname.a  来指定依赖的库文件 。
Linux下约定所有库都以前缀lib开始静态库以.a结尾,动态库以.so结尾。再编译程式时,无需带上前缀和后缀

在编译过程中,-L指定的路径是编译路径 ,而在运行时需要动态的搜索库文件 ,这两个路径不是一个概念 。因此经常会出现这样的问题 :

”明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过“-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你 要作的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题 了。










最新文章

  1. JS原生ajax与Jquery插件ajax深入学习
  2. C#的两个大方向
  3. HBase1.0以上版本的API改变
  4. EF结合三层:三层中数据层父类和业务层父类的使用
  5. 转: when.js原理和核心实现
  6. $.ajax和$.post的区别(前者根据key-value/后者根据形参)
  7. 【python】函数filter、map
  8. Vue-框架模板的源代码注释
  9. 插件开发之360 DroidPlugin源码分析(五)Service预注册占坑
  10. Placement of class definition and prototype
  11. VSCODE安装以及使用Python运行调试代码的简单记录
  12. spring注解第07课 @Valid和@Validated的总结区分
  13. (2018干货系列十一)最新iOS学习路线整合
  14. EPPlus实战篇——Excel写入
  15. docker容器扫盲
  16. jq无缝滚动效果插件(之前的那个升级改造加强版)
  17. 条件触发和边缘触发 及 epoll 的长处
  18. git删除所有提交历史记录
  19. JavaScript互斥锁案例
  20. [SIP01]SIP Header Fields里面各字段用途

热门文章

  1. BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划( dp)
  2. 条款20:宁以pass-by-reference-to-const替换pass-by-value
  3. [条款36]绝不重新定义继承而来的non-virtual函数
  4. 关于RMAN的配置信息存储和控制文件的关系
  5. linux分区工具fdisk的使用
  6. EAN 通用商品条形码
  7. 王立平--android事件监听的3种方式
  8. Android自动化测试基础知识——MONKEY测试工具(转的)
  9. C++,常成员函数
  10. PigCms 回复消息 &quot;域名授权错误! 您使用的微信平台或源码为盗版&quot;