静态库

先说说我们为什么需要库?

当有些代码我们大量会在程序中使用比如(scanf,printf等)这些函数我们需要在程序中频繁使用,于是我们就把这些代码编译为库文件,在需要使用时我们直接链接即可。

定义:

 程序在编译时把静态库的代码链接到可执行程序中,在代码运行时不再需要静态库。(简单理解就是把一堆 .o 文件打包到一起,当需要用到就让我们的程序链接进来)

生成及使用方法:

  这里用加减乘除来举例示意:

  1. //创建所需文件
  2. [root@localhost ku]# touch add.c add.h sub.c sub.h mul.c mul.h dev.c dev.h main.c
  3. [root@localhost ku]# ls
  4. add.c add.h dev.c dev.h main.c mul.c mul.h sub.c sub.h
  5. [root@localhost ku]#
  6. //编写所有文件代码
  7. //add.c
  8. #include"add.h"
  9. int add(int x,int y)
  10. {
  11. return x+y;
  12. }
  13. //add.h
  14. #ifndef __ADD_H__
  15. #define __ADD_H__
  16. int add(int x,int y);
  17. #endif // __ADD_H__
  18. //sub.c
  19. #include"sub.h"
  20. int sub(int x,int y)
  21. {
  22. return x-y;
  23. }
  24. //sub.h
  25. #ifndef __SUB_H__
  26. #define __SUB_H__
  27. int sub(int x,int y);
  28. #endif // __SUB_H__
  29. //mul.c
  30. #include"mul.h"
  31. int mul(int x,int y)
  32. {
  33. return x*y;
  34. }
  35. //mul.h
  36. #ifndef __MUL_H__
  37. #define __MUL_H__
  38. int mul(int x,int y);
  39. #endif //__MUL_H__
  40. //dev.c
  41. #include"dev.h"
  42. int dev(int x,int y)
  43. {
  44. return x/y;
  45. }
  46. //dev.h
  47. #ifndef __DEV_H__
  48. #define __DEV_H__
  49. int dev(int x,int y);
  50. #endif // __DEV_H__
  51. //main.c
  52. #include<stdio.h>
  53. #include"add.h"
  54. #include"sub.h"
  55. #include"mul.h"
  56. #include"dev.h"
  57. int main()
  58. {
  59. int a,b;
  60. scanf("%d%d",&a,&b);
  61. printf("%d + %d = %d\n",a,b,add(a,b));
  62. printf("%d - %d = %d\n",a,b,sub(a,b));
  63. printf("%d * %d = %d\n",a,b,mul(a,b));
  64. printf("%d / %d = %d\n",a,b,dev(a,b));
  65. return 0;
  66. }
  67. //编译源文件
  68. [root@localhost ku]# ls
  69. add.c add.h dev.c dev.h main.c mul.c mul.h sub.c sub.h
  70. [root@localhost ku]# gcc -c *.c //把所有.c文件生成.o文件
  71. [root@localhost ku]# ls
  72. add.c add.h add.o dev.c dev.h dev.o main.c main.o mul.c mul.h mul.o sub.c sub.h sub.o
  73. [root@localhost ku]# rm main.o -rf //删除多余的.o文件
  74. [root@localhost ku]# ls
  75. add.c add.h add.o dev.c dev.h dev.o main.c mul.c mul.h mul.o sub.c sub.h sub.o
  76. [root@localhost ku]#
  77. //生成静态库
  78. [root@localhost ku]# ar -rc libmycal.a *.o
  79. [root@localhost ku]# ls
  80. add.c add.h add.o dev.c dev.h dev.o libmycal.a main.c mul.c mul.h mul.o sub.c sub.h sub.o
  81. [root@localhost ku]#
  82. //查看静态库
  83. [root@localhost ku]# ls
  84. add.c add.h add.o dev.c dev.h dev.o libmycal.a main.c mul.c mul.h mul.o sub.c sub.h sub.o
  85. [root@localhost ku]# ar -tv libmycal.a
  86. rw-r--r-- 0/0 683 Apr 26 20:46 2018 add.o
  87. rw-r--r-- 0/0 683 Apr 26 20:46 2018 dev.o
  88. rw-r--r-- 0/0 679 Apr 26 20:46 2018 mul.o
  89. rw-r--r-- 0/0 687 Apr 26 20:46 2018 sub.o
  90. [root@localhost ku]#
  91. //链接静态库生成可执行文件
  92. [root@localhost ku]# ls
  93. add.c add.h add.o dev.c dev.h dev.o libmycal.a main.c mul.c mul.h mul.o sub.c sub.h sub.o
  94. [root@localhost ku]# gcc main.c -L. -lmycal
  95. [root@localhost ku]# ls
  96. add.c add.h add.o a.out dev.c dev.h dev.o libmycal.a main.c mul.c mul.h mul.o sub.c sub.h sub.o
  97. [root@localhost ku]#
  98. //运行结果
  99. [root@localhost ku]# ls
  100. add.c add.h add.o a.out dev.c dev.h dev.o libmycal.a main.c mul.c mul.h mul.o sub.c sub.h sub.o
  101. [root@localhost ku]# ./a.out
  102. 8 3
  103. 8 + 3 = 11
  104. 8 - 3 = 5
  105. 8 * 3 = 24
  106. 8 / 3 = 2
  107. [root@localhost ku]#

以上是整个静态库的生成及运用过程

总结起来就3步骤:

 首先将源文件编译成目标文件:gcc –c 源文件

 生成静态库:ar –rc lib(库名).a 目标文件

 使用静态库:gcc main.c -L(库的路径) -l(库名)

静态库的优缺点

优点:

 1. 省空间:linker只会复制你用到的objects。

 2. 打包简单。

缺点:

 1、如果静态库中有全局变量,那么在几个模块中使用,将会导致全局变量有不同的值,这是非常严重的问题。

 2、静态库编译时,不会进行链接检查,所以这么多静态库的问题,在生成静态库阶段检查不出来。

 3、几个模块,引用同一静态库,如果有一模块没有编译到,会引起巨大的差异导致问题。

 4.产生大量的库文件文件会占空间

动态库

定义:

 程序在运行时才去链接动态库的代码,多个程序共享使用库的代码。

 一个与动态库链接的可执行文件仅包含他用到的函数入口地址的一个表,而不是外部函数所在目标文件的机器码。

生成及使用方法:

事例程序和上面一样,这里只写出操作步骤

  1. [root@localhost ku]# ls
  2. add.c add.h dev.c dev.h main.c mul.c mul.h sub.c sub.h
  3. [root@localhost ku]# gcc -c -fpic *.c
  4. // -fpic 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
  5. [root@localhost ku]# ls
  6. add.c add.h add.o dev.c dev.h dev.o main.c main.o mul.c mul.h mul.o sub.c sub.h sub.o
  7. [root@localhost ku]# rm main.o -rf
  8. [root@localhost ku]# ls
  9. add.c add.h add.o dev.c dev.h dev.o main.c mul.c mul.h mul.o sub.c sub.h sub.o
  10. [root@localhost ku]# gcc -shared -o libmycal.so *.o
  11. [root@localhost ku]# ls
  12. add.c add.h add.o dev.c dev.h dev.o libmycal.so main.c mul.c mul.h mul.o sub.c sub.h sub.o
  13. [root@localhost ku]# gcc main.c -L. -lmycal
  14. //-L. 表示要连接的库在当前目录中
  15. [root@localhost ku]# ls
  16. add.c add.h add.o a.out dev.c dev.h dev.o libmycal.so main.c mul.c mul.h mul.o sub.c sub.h sub.o
  17. [root@localhost ku]# ./a.out
  18. ./a.out: error while loading shared libraries: libmycal.so: cannot open shared object file: No such file or directory
  19. [root@localhost ku]# cp libmycal.so /lib/
  20. //把动态库移动到系统库文件下
  21. [root@localhost ku]# ls
  22. add.c add.h add.o a.out dev.c dev.h dev.o libmycal.so main.c mul.c mul.h mul.o sub.c sub.h sub.o
  23. //运行结果
  24. [root@localhost ku]# ./a.out
  25. 8 6
  26. 8 + 6 = 14
  27. 8 - 6 = 2
  28. 8 * 6 = 48
  29. 8 / 6 = 1
  30. //第二种方法,更改库路径
  31. [root@localhost ku]# ./main
  32. ./main: error while loading shared libraries: libmycal.so: cannot open shared object file: No such file or directory
  33. [root@localhost ku]# vim /etc/ld.so.conf.d/mycal.conf //在创建的文件里写上库的路径
  34. //写好路径之后刷新缓冲区
  35. [root@localhost ku]# ldconfig
  36. //运行结果
  37. [root@localhost ku]# ./main
  38. 8 6
  39. 8 + 6 = 14
  40. 8 - 6 = 2
  41. 8 * 6 = 48
  42. 8 / 6 = 1

动态库优缺点:

优点:

 1 .共享内存

 2 .独立升级组件(插件安装,软件更新)

 3.可以显示动态加载

缺点:

 1.当系统中多个应用程序都用了一个动态链接库,但是要求的版本不同,这时动态链接库之间就会相互干扰。

 2.性能开销。动态链接库为了做到“共享代码,但是不共享数据”,引入了不小的开销,调用动态链接库中的函数,需要好几次间接内存访问才能走到函数入口,全局数据也是。

linux下的静态库与动态库的更多相关文章

  1. Linux 下的静态(函数)库、动态(函数)库

    0. 基本 在命名上,静态库的名字一般是 libxxx.a,动态库的名字一般是 libxxx.so,有时 libxxx.so.major.minor,xxx 是该 lib 的名字,major 是主版本 ...

  2. linux下添加动态链接库路径、动态库加载等方法

    linux下添加动态链接库路径的方法 2017年01月20日 10:08:17 阅读数:5596   Linux共享库路径配置 Linux下找不到共享库文件的典型现象为明明已经安装某个软包(如libn ...

  3. linux下项目开发加载动态库:ldconfig与 /etc/ld.so.conf

    场景:自己开发一个项目,程序里包含一些自定义动态库.运行,需要加载这些动态库. 假如这些库在/pro/output/lib/下面,可执行程序在/pro/output/bin/下面. 那么,我们需要: ...

  4. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  5. 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库

      最近在编写的一个Apache  kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a    静态库编译的,,,而我们这 ...

  6. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  7. [转]Linux下用gcc/g++生成静态库和动态库(Z)

    Linux下用gcc/g++生成静态库和动态库(Z) 2012-07-24 16:45:10|  分类: linux |  标签:链接库  linux  g++  gcc  |举报|字号 订阅     ...

  8. linux下的共享库(动态库)和静态库

    1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...

  9. 【转】Linux下gcc生成和使用静态库和动态库详解

    一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不 ...

  10. (笔记)Linux下的静态库和动态库使用详解

    库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比 ...

随机推荐

  1. 3.5星|《硅谷产品》:Facebook网红社区产品经理经验谈

    硅谷产品:36讲直通世界级产品经理 作者是Facebook产品经理,目前负责的具体业务书的扉页上有含糊的介绍,书中没明确说,根据书中内容推测,主要是网红社区. 比较遗憾的是书中作者亲历的案例只有3个. ...

  2. 16:42 python历史

    python的作者是Guido van Rossum,大牛,2.7版本好像到2020年就不能用了,估计很多公司对此有很多的需求吧.

  3. IntelliJ 禁用 Search Everywhere

    发现自: https://youtrack.jetbrains.com/issue/IDEA-114933#comment=27-603899 Open lib/resources.jar/idea/ ...

  4. JavaScript的DOM操作获取元素的大小

    通过 style 内联获取元素的大小 需要注意的是style 获取只能获取到行内 style 属性的 CSS 样式中的宽和高,如果有获取:如果没有则返回空. <!DOCTYPE html> ...

  5. Python全栈开发:list 、tuple以及dict的总结

    总结: 列表:增:append(),inset(),extend() 删:pop(),remove(),clear(),del 改:a.通过指定元素和切片重新赋值.b.可以使用repelace替换列表 ...

  6. Java基础加强之并发(四)synchronized关键字

    并发系列参考文章http://www.cnblogs.com/skywang12345/p/3323085.html#3907193 synchronized原理 在java中,每一个对象有且仅有一个 ...

  7. [luogu3943] 星空

    题面 ​ 这个题目大意上是这样的:给定一个长度为n的01串, 其中只有k个0, 每次操作时, 从给定的m种长度中选择一种, 选择序列上长度为这种的进行反转操作, 求至少需要多少次操作使得整个串全变为1 ...

  8. python matplotlib quiver——画箭头、风场

    理解参考:https://blog.csdn.net/liuchengzimozigreat/article/details/84566650 以下实例 import numpy as np impo ...

  9. Servlet 处理请求

    一:Servlet 处理请求也是通过request来进行处理,类似于python. get请求通过request.getparameter("key");key为前端传过来的key ...

  10. locust

    from locust import HttpLocust,TaskSet,task class UserVue(TaskSet): #tasks = {buy:1,consume:2} #设置权重 ...