设为首页 收藏本站
查看: 542|回复: 0

[经验分享] Linux静态库与动态库详解

[复制链接]

尚未签到

发表于 2017-11-17 21:34:08 | 显示全部楼层 |阅读模式
引言
  

为了代码的复用性和模块化,我们常常使用一些库文件,在Windows操作系统下位.lib  .dll作为静态库和动态库的后缀名。  

  
在Linux下,静态链接库名字一般为libabcdef.a,其中abcdef为该lib的名称
  动态链接库名字一般为libabcde.so.major.minor,abcde为该lib的名称,major是主版本号,minor是副版本号
  

  下面来分别介绍一下静态链接库和动态链接库

静态库


  • 生成静态库。(以.a为后缀名)  
    编写如下程序:

  
/////////////////////////////////////////////////////////////////////////////////////
  
/* program1.   hello.h */
  

  
#ifndef HELLO_H
  
#define HELLO_H
  

  
void hello(const char *name);
  

  
#endif
  
/////////////////////////////////////////////////////////////////////////////////////
  

  

  
/////////////////////////////////////////////////////////////////////////////////////
  
/* program2.   hello.c */
  
#include <stdio.h>
  
void hello(const char *name) {
  printf("hello, %s\n", name);
  
}
  
/////////////////////////////////////////////////////////////////////////////////////
  

  

  
/////////////////////////////////////////////////////////////////////////////////////
  
/* program3.   main.c */
  
#include "hello.h"
  
int main(char argc, char *argv[])
  
{
  hello("world");
  return 0;
  
}
  
/////////////////////////////////////////////////////////////////////////////////////
  编译hello.c,生成一个可重定位的目标文件hello.o
$gcc -c hello.c  Linux环境下使用ar工具创建一个静态库,或者将目标文件加入到一个已经存在的静态库中。并使用方法如下:
$ar rcs 静态库名 目标文件1 目标文件2...目标文件n  该明亮表示将目标文件1~n加入到指定的静态库中。如果该静态库不存在,则创建静态库文件,并且将库文件的扩展名
  
命名为.a,其中ar工具的参数rcs弃了至关重要的作用。这3个参数分别表示:把列表中的目标文件加入到静态库中(参数r);
  
若指定的静态库不存在,则创建该库文件(参数c);最后更新静态库文件的索引,使之包含新加入的目标文件的文件内容(参数s).
  
现在,我们需要使用刚生成的hello.o目标文件,创建一个静态库文件libmyhello.a,其执行命令如下:
$ar rcs libmyhello.a hello.o  静态库制作完毕以后,可以看到在当前目录下生成了libmyhello.a文件
  备注:在某些系统中还要为静态库生成一个内容表
$ranlib libmyhello.a

  • 使用静态链接库  
    在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成可执行文件时,指明静态库的名字。
      
    gcc将会从静态库中将公用函数连接到目标文件中。
      
    备注:gcc会在静态库名前加上前缀lib, 然后追加扩展名.a得到的静态库文件名来查找静态库文件。因此,我们在写需要连接到库时,
      
    只写名字就可以。如libmyhello.a的库,只写-lmyhello

$gcc main.c -L. -lmyhello  可以看到编译通过,并在当前目录下生成a.out可执行文件,执行可执行文件,即可生成hello, world
  如果想在编译的时候修改可执行文件的名字,可以使用如下命令:
$gcc main.c -L. -lmyhello -o x_main  使用gcc的-l选项来指定静态库,或者使用-L参数来指定库文件的搜索路径。
  
-l和-L之后都直接带参数而不跟空格。因此,这里“."作为静态库的搜索路径。
  注意:在使用gcc链接静态库的时候的,其参数的顺序。
  
-l是链接器选项,一定要放在被编译的源文件的文件名称之后,也就是本例中的main.c文件之后。若放在文件名称之前,则会链接失败。
  
gcc也支持使用-static选项对静态库进行链接。
  因为静态库是直接编译到可执行文件中,我们可以删除掉当前目录下的libmyhello.a文件,
  
然后重新执行可执行文件,可以看到:程序的结果与之前一样,表明静态库文件已经成功链接到可执行文件中了。
  静态链接库的缺点:
  
如果我们同时运行了许多程序,并且它们使用了同一个库函数,这样,在内存中会大量拷贝同一个库函数。这样就会浪费掉很多珍贵的内存和存储空间。
  
使用动态链接库就可以避免这个问题。
  当静态库与动态库同名时,gcc命令默认将优先使用动态库。

动态库(未验证)
  1.在程序中使用动态库
  
(1)如果是标准C语言库我们可以不指定其库路径和库名称
  
(2)如果静态库处于/lib或/usr/lib下
  
$gcc -o test test.c /usr/lib/libm.a 或 $gcc -o test test.c -lm
  
他们的效果相同。-lm意味着命名为libm.a或libm.so的文件(注意Linux下的库文件都要以lib开头)。
  参考:
  
《Linux C程序设计大全》吴岳等编著
  
https://wenku.baidu.com/view/7d8602b265ce050877321301.html
  
http://general.blog.51cto.com/927298/269044

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-408041-1-1.html 上篇帖子: Linux系统学习之文件管理 下篇帖子: Linux源码编译处理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表