静态库,动态库,静态链接和动态链接

静态库,动态库,静态链接和动态链接这几个概念理解起来很简单,本文主要是收集了网上的一些观点作了一个较全面的总结。
一、问题
1,静态库是什么?
2,动态库是什么?
3,两者的区别?


4,静态链接?
5,动态链接?
6,两者的区别?


7,静态库能否动态链接?动态库能否静态链接?
二、关于库
1,库的原则
      现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始。尽量不重复做别人已经做过的事,就是尽量充分利用别人的劳动成果。就是“站在巨人的肩膀上”做事情。
2,静态库与动态库
      静态库的名字一般是libxxx.a(Linux)。
      动态库的名字一般是libxxx.so(Linux),有时候也是 libxxx.so.major.minor.z,xxxx是该lib的名称,major是主版本号,minor是副版本号,z称为发布号。
      静态库的所有数据都会被整合进目标代码中,因此编译成的文件比较大。它的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,(1)首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。(2)再者,一旦发现了静态函数库改变或库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。而动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。
      共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅是简单的引用,因此代码体积较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。
3,共享库
      Linux下的共享库类似windows下的dll,共命令约定如下:静态库一般由字母 lib 开头,并有 .a 的扩展名,而共享对象有两个不同的名称:soname 和 real name。soname包含前缀"lib",然后紧跟库名,其次是 ".so"(后面紧跟另一个圆点),以及表明主版本号的数字。soname 可以由前缀的路径信息来限定。real name 是包含库的已编译代码的真正文件名。real name 在 soname 后添加一个圆点、小的数字、另外一个圆点和发布号。格式如下: 
      libxxxx.so.major.minor
      其中,xxxx是库的名字,major是主版本号,minor 是次版本号或叫发布号,次版本号和其相应的圆点是可选的。soname是记录在共享库中的,其它库使用这个共享库时,实际上只需要的提供soname,动态链接器会找到名称是soname的动态库给程序使用。


      这种带版本号的共享库主要是为了你可以很方便的升级你的函数库,如果某个API改变了,创建库的程序会改变主版本号,然而,如果一个函数升级了某个函数库,而功能没有发生变化,这时只需要改变次版本号,由于只改变了次版本号,所以soname没有发生改变,这样就可以做到与旧的共享库保持兼容。
4,如何判断一个程序有没有链接动态库
      (1)file命令
      file程序是用来判断文件类型的,啥文件一看都清楚明了。
      (2)ldd命令
      看动态库,如果目标程序没有链接动态库,则打印“not a dynamic executable” (不是动态可执行文件)
      <file :run和run_dyn都是可运行文件,action.h上一个ASCII C++文件>
      <ldd: run_dyn 使用了共享库,action.o是不动态可执行文件>
5,库依赖的查看
      使用ldd命令来查看执行文件依赖于哪些库。该命令用于判断某个可执行的 binary 档案含有什么动态函式库。
      # ldd [-vdr] [filename]
      参数说明:
      --version  打印ldd的版本号
      -v --verbose  打印所有信息,例如包括符号的版本信息
      -d --data-relocs  执行符号重部署,并报告缺少的目标对象(只对ELF格式适用)
      -r --function-relocs  对目标对象和函数执行重新部署,并报告缺少的目标对象和函数(只对ELF格式适用)
      --help 用法信息。
      如果命令行中给定的库名字包含'/',这个程序的libc5版本将使用它作为库名字;否则它将在标准位置搜索库。运行一个当前目录下的共享库,加前缀"./"。
6,编译时相关的GCC参数
      -Idir 
      添加头文件的查找路径
      -llibrary 
      指定编译的时候使用的库
      gcc -lcurses hello.c  #使用ncurses库编译程序
      -Ldir
      指定编译的时候,搜索库的路径。比如你自己的库,可以用它指定目录,不然编译器将只在标准库的目录找。这个dir就是目录的名称。
      -static
      此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么动态连接库,就可以运行.
      (On systems that support dynamic linking, this prevents linking with the shared libraries.  On other systems, this option has no effect.)
      -share
      此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
      (Produce a shared object which can then be linked with other objects to form an executable.  Not all systems support this option. For predictable results, you must also specify the same set of options that were used to generate code (-fpic, -fPIC, or model suboptions) when you specify this option.)
7,linux下库文件是如何产生的
      (1)静态库
      静态库的后缀是.a,它的产生分两步(-static):
      Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表【gcc -c/-S -o hello.o/hello.s hello.c】
      Step 2.ar命令将很多.o转换成.a,成文静态库【ar....ld....】
      (2)动态库

      动态库的后缀是.so,它由gcc加特定参数(-fpic -shared)编译产生。








http://hi.baidu.com/wangsenlin88/item/7f8dd40329ca0bd41ff046df

http://blog.sina.com.cn/s/blog_54f82cc201011oqv.html

http://hi.baidu.com/jfojfo/item/5fc5de3c3b9ebbf2e6bb7a03

http://www.360doc.com/content/12/1016/12/10885655_241788849.shtml

http://bbs.csdn.net/topics/320091330

相关参考:

http://www.cnblogs.com/feisky/archive/2010/03/09/1681996.html

http://blog.csdn.net/wangwenwen/article/details/7308073

http://blog.csdn.net/lishenglong666/article/details/7219917

http://www.cnblogs.com/hongzg1982/articles/2163787.html

http://blog.csdn.net/tutengwolf/article/details/5191214

http://blog.csdn.net/lishenglong666/article/details/7219917

http://blog.csdn.net/feimashenhua/article/details/6252713

http://blog.csdn.net/mtk_kyle/article/details/2317787

http://linux.chinaitlab.com/administer/870254.html

 -fpic 使输出的对象模块是按照可重定位地址方式生成的。     

 -shared指定把对应的源文件生成对应的动态链接库文件。

http://tech.ccidnet.com/art/302/20080428/1433567_1.html

http://cache.baidu.com/c?m=9d78d513d9d431ab4f9ee0697c67c015684381132ba7a40208d48449e3732a4b5011e6ac57510775a4d27d1716de424b9e832102361451bc8f8fc814d2e1d46e6d9f26476d01c30457c419d8951d79866acb0cb8b81990ebad6d8ed0898f981e4eca51067a97f0fd580009cd68f1143bf4a6ee125300&p=8b2a9f1389df04ff57ee927a177a90&newp=8f71d116d9c95df613bd9b7d0b1291231610db2151d3d409269f&user=baidu&fm=sc&query=%B6%AF%CC%AC%BF%E2%C8%E7%BA%CE%C9%FA%B3%C9&qid=b5283f2f4117f19b&p1=25

http://www.linuxidc.com/Linux/2012-02/55328.htm

http://www.cnblogs.com/hongzg1982/articles/2163787.html

http://bbs.chinaunix.net/thread-1285426-1-1.html

http://bbs.chinaunix.net/thread-1035042-1-1.html

http://hi.baidu.com/ppc919/item/8d66cac72dc4f67a88ad9e65

COW:

http://baike.baidu.com/view/204208.htm#3

GOT:

http://baike.baidu.com/view/2420839.htm

GOT与PLT:

http://cache.baidu.com/c?m=9d78d513d9961ce94fece4697b17c011694381137e8996013894cd47c9221d03506790a63a724e5986d27c1040f4150ffdf041236a5c37b7ec99d4579ca6c27672dd3033041b801518d348fecb4426c3239307aaeb0ee7cdaa74ccf0&p=8671dc1887934eac58ec822d0215d532&newp=882a9645d7850ef30be2977c4b059f315c5bc4387ebad3157e92dc14&user=baidu&fm=sc&query=got%D3%EBplt&qid=99047a6a41d17dad&p1=4

http://blog.sina.com.cn/s/blog_54f82cc201011oqv.html

http://hi.baidu.com/jfojfo/item/5fc5de3c3b9ebbf2e6bb7a03

http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f76238d586482ec3933fc239045c163bbffd707e5619d0c5616403ac4d41e9f02b7135092ab09fcf8f5ddacf922e2c8d2d3e7a1a8d5612a458f58d197bd565cd1abfa04cbafce733e3b9a4d2c82323dd527538deb6&p=987bc116d9c046b708e2917c5b508b&newp=882a90478d990bb14681c7710e1182231615d70e3fd4d11e248ed9568d08&user=baidu&fm=sc&query=got%D3%EBplt&qid=99047a6a41d17dad&p1=9

http://www.360doc.com/content/12/1016/12/10885655_241788849.shtml

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值