Chinaunix首页 | 论坛 | 博客
  • 博客访问: 390036
  • 博文数量: 62
  • 博客积分: 388
  • 博客等级: 一等列兵
  • 技术积分: 1032
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-03 20:18
文章分类

全部博文(62)

文章存档

2017年(5)

2016年(3)

2015年(3)

2014年(8)

2013年(15)

2012年(28)

分类: C/C++

2013-12-30 17:34:23

动态库及静态库的区别

二者的不同点在于代码被载入的时刻不同。

静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

静态库的后缀名为.a文件.当程序与一个静态库链接时,该程序用到的外部函数的机器码被从库中复制到最终生成的可执行文件中.
动态库(共享库)的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小.
   一个与共享库链接的可执行文件仅仅包含它用到的函数相关的一个表格,而不是那个函数的整个机器码.在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该共享库中复制到内存中.


因此,当程序编译后,删除或修改静态库及路径,对程序没有影响;但若是动态库,删除或修改动态库及路径,程序将会出错。


编译及使用


gcc -I 指定搜索头文件目录  系统默认路径为 /usr/include  /usr/local/include 以及/usr/lib/gcc下的一些include目录

      -L 指定搜索静态库、动态库路径 系统默认路径为  /lib、/usr/lib、/usr/local/lib、 /usr/lib64, 也可在 /etc/ld.so.conf中指定,也可LD_LIBRARY_PATH环境 变量来指定 默认情况下,gcc在链接时优先使用动态库,只有当动态库不存在时才考虑使用静态库,如果需要的话可以在编译时加上-static选项,强制使用静态库。如:gcc foo.c -L /home/xiaowp/lib -static -lfoo; -L.(点):表示要连接的库在当前目录中

      -l 需要加载的库名 若库命名为 libfoo.a 或 libfoo.so  则 -lfoo。若在本地则不需要指定目录 直接将库名添加一块编译,如 gcc -o test  a.o b.o c.a d.so


同时也可以链接的方式来讲文件链接到系统默认路径 ln -s source dest


静态库编译

gcc -c hello.c   ==> hello.o
   gcc -c bye.c     ==> bye.o
   然后生成静态库和动态库
   ar cr libhello.a hello.o bye.o
   ar是GNU的归档器,可以从对象生成静态库 cr 代表 "creat andd replace".如果库文件不存在则会创建.如果库文件已经存在,任何与它同名的原始文件将被命令上指定的新文件取代.
   归档工具ar也提供了"内容列表"的选项"t"来列出已有库中的对象文件:
   ar t libhello.a 
   hello.o
   bye.o


动态库编译

gcc -fPIC -o lt.o -c lt.c  //最好加上fPIC选型,否则share时可能报.o未加fPIC选型
gcc -shared -Wall -fPIC -o liblt.so lt.o  
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。


ldd 查看程序所需要的库 

如  ldd test

   linux-gate.so.1 => (0xffffe000)
   liblt.so => /usr/lib/liblt.so (0xb7f58000)
   libc.so.6 => /lib/libc.so.6 (0xb7e28000)
   /lib/ld-linux.so.2 (0xb7f6f000)

阅读(3003) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~