博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux下的静态库与动态库详解
阅读量:5318 次
发布时间:2019-06-14

本文共 5974 字,大约阅读时间需要 19 分钟。

静态库

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

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

定义:

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

生成及使用方法:

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

//创建所需文件[root@localhost ku]# touch add.c add.h sub.c sub.h mul.c mul.h dev.c dev.h main.c [root@localhost ku]# lsadd.c  add.h  dev.c  dev.h  main.c  mul.c  mul.h  sub.c  sub.h[root@localhost ku]# //编写所有文件代码//add.c#include"add.h"                                                                                                                       int add(int x,int y){    return x+y;}//add.h #ifndef __ADD_H__#define __ADD_H__int add(int x,int y);                                                                                                                                       #endif // __ADD_H__//sub.c#include"sub.h"int sub(int x,int y)                                                                                                                  {    return x-y;}//sub.h#ifndef __SUB_H__#define __SUB_H__int sub(int x,int y); #endif // __SUB_H__  //mul.c#include"mul.h"int mul(int x,int y)                                                                                                                  {    return x*y;}//mul.h#ifndef __MUL_H__#define __MUL_H__int mul(int x,int y); #endif //__MUL_H__   //dev.c#include"dev.h"int dev(int x,int y)                                                                                                                  {    return x/y;}//dev.h#ifndef __DEV_H__ #define __DEV_H__int dev(int x,int y);                                                                                                                 #endif // __DEV_H__//main.c#include
#include"add.h"#include"sub.h"#include"mul.h"#include"dev.h"int main(){ int a,b; scanf("%d%d",&a,&b); printf("%d + %d = %d\n",a,b,add(a,b)); printf("%d - %d = %d\n",a,b,sub(a,b)); printf("%d * %d = %d\n",a,b,mul(a,b)); printf("%d / %d = %d\n",a,b,dev(a,b)); return 0;}//编译源文件[root@localhost ku]# lsadd.c add.h dev.c dev.h main.c mul.c mul.h sub.c sub.h[root@localhost ku]# gcc -c *.c //把所有.c文件生成.o文件[root@localhost ku]# lsadd.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[root@localhost ku]# rm main.o -rf //删除多余的.o文件[root@localhost ku]# lsadd.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[root@localhost ku]# //生成静态库[root@localhost ku]# ar -rc libmycal.a *.o[root@localhost ku]# lsadd.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[root@localhost ku]# //查看静态库[root@localhost ku]# lsadd.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[root@localhost ku]# ar -tv libmycal.a rw-r--r-- 0/0 683 Apr 26 20:46 2018 add.orw-r--r-- 0/0 683 Apr 26 20:46 2018 dev.orw-r--r-- 0/0 679 Apr 26 20:46 2018 mul.orw-r--r-- 0/0 687 Apr 26 20:46 2018 sub.o[root@localhost ku]# //链接静态库生成可执行文件[root@localhost ku]# lsadd.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[root@localhost ku]# gcc main.c -L. -lmycal[root@localhost ku]# lsadd.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[root@localhost ku]# //运行结果[root@localhost ku]# lsadd.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[root@localhost ku]# ./a.out 8 38 + 3 = 118 - 3 = 58 * 3 = 248 / 3 = 2[root@localhost ku]#

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

总结起来就3步骤:

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

 生成静态库:ar –rc lib(库名).a 目标文件
 使用静态库:gcc main.c -L(库的路径) -l(库名)

静态库的优缺点

 优点:

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

 2. 打包简单。

 缺点:

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

 2、静态库编译时,不会进行链接检查,所以这么多静态库的问题,在生成静态库阶段检查不出来。
 3、几个模块,引用同一静态库,如果有一模块没有编译到,会引起巨大的差异导致问题。
 4.产生大量的库文件文件会占空间

动态库

定义:

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

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

生成及使用方法:

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

[root@localhost ku]# lsadd.c  add.h  dev.c  dev.h  main.c  mul.c  mul.h  sub.c  sub.h[root@localhost ku]# gcc -c -fpic *.c// -fpic   表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。[root@localhost ku]# lsadd.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[root@localhost ku]# rm main.o -rf[root@localhost ku]# lsadd.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[root@localhost ku]# gcc -shared -o libmycal.so *.o[root@localhost ku]# lsadd.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[root@localhost ku]# gcc main.c -L. -lmycal//-L.   表示要连接的库在当前目录中[root@localhost ku]# lsadd.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[root@localhost ku]# ./a.out ./a.out: error while loading shared libraries: libmycal.so: cannot open shared object file: No such file or directory[root@localhost ku]# cp libmycal.so /lib///把动态库移动到系统库文件下[root@localhost ku]# lsadd.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//运行结果[root@localhost ku]# ./a.out 8 68 + 6 = 148 - 6 = 28 * 6 = 488 / 6 = 1//第二种方法,更改库路径[root@localhost ku]# ./main ./main: error while loading shared libraries: libmycal.so: cannot open shared object file: No such file or directory[root@localhost ku]# vim /etc/ld.so.conf.d/mycal.conf //在创建的文件里写上库的路径//写好路径之后刷新缓冲区[root@localhost ku]# ldconfig //运行结果[root@localhost ku]# ./main 8 68 + 6 = 148 - 6 = 28 * 6 = 488 / 6 = 1

动态库优缺点:

优点:

 1 .共享内存

 2 .独立升级组件(插件安装,软件更新)
 3.可以显示动态加载

缺点:

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

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

转载于:https://www.cnblogs.com/zhonglongbo/p/8975815.html

你可能感兴趣的文章
走楼梯
查看>>
C# JSON字符串序列化与反序列化
查看>>
HTTPS、SPDY和HTTP/2的性能比较
查看>>
Java变量类型,实例变量 与局部变量 静态变量
查看>>
Angular实践----理解数据绑定过程
查看>>
sublime快捷键
查看>>
mysql操作命令梳理(4)-中文乱码问题
查看>>
Hyper-V Centos7 网络设置 虚拟机固定IP
查看>>
Python环境搭建(安装、验证与卸载)
查看>>
一个.NET通用JSON解析/构建类的实现(c#)
查看>>
Windows Phone开发(31):画刷 转:http://blog.csdn.net/tcjiaan/article/details/7460226
查看>>
Windows Phone开发(5):室内装修 转:http://blog.csdn.net/tcjiaan/article/details/7269014
查看>>
记Angular与Django REST框架的一次合作(2):前端组件化——Angular
查看>>
08.存储Cinder→5.场景学习→08.Backup Volume→1.概述与配置
查看>>
进阶之路(基础篇) - 012 Arduino IDE 添加DHT11传感器第三方库的方法
查看>>
详谈js面向对象 javascript oop,持续更新
查看>>
Javaweb Tomcat 项目部署方式
查看>>
文字半透明显示在图片上
查看>>
express简单原理
查看>>
ubuntu安装spark on yarn
查看>>