linux下的静态库与动态库

目录

  • 静态库
    • 定义:
    • 生成及使用方法:
    • 静态库的优缺点
  • 动态库
    • 定义:
    • 生成及使用方法:
    • 动态库优缺点:

静态库

先说说我们为什么需要库?
当有些代码我们大量会在程序中使用比如(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]# ls
add.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<stdio.h>
#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]# ls
add.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]# ls
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
[root@localhost ku]# rm main.o -rf  //删除多余的.o文件
[root@localhost ku]# ls
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
[root@localhost ku]# 
//生成静态库
[root@localhost ku]# ar -rc libmycal.a *.o
[root@localhost ku]# ls
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
[root@localhost ku]# 
//查看静态库
[root@localhost ku]# ls
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
[root@localhost ku]# ar -tv libmycal.a 
rw-r--r-- 0/0    683 Apr 26 20:46 2018 add.o
rw-r--r-- 0/0    683 Apr 26 20:46 2018 dev.o
rw-r--r-- 0/0    679 Apr 26 20:46 2018 mul.o
rw-r--r-- 0/0    687 Apr 26 20:46 2018 sub.o
[root@localhost ku]# 
//链接静态库生成可执行文件
[root@localhost ku]# ls
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
[root@localhost ku]# gcc main.c -L. -lmycal
[root@localhost ku]# ls
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
[root@localhost ku]# 
//运行结果
[root@localhost ku]# ls
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
[root@localhost ku]# ./a.out 
8 3
8 + 3 = 11
8 - 3 = 5
8 * 3 = 24
8 / 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]# ls
add.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]# ls
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
[root@localhost ku]# rm main.o -rf
[root@localhost ku]# ls
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
[root@localhost ku]# gcc -shared -o libmycal.so *.o
[root@localhost ku]# ls
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
[root@localhost ku]# gcc main.c -L. -lmycal
//-L.   表示要连接的库在当前目录中
[root@localhost ku]# ls
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
[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]# ls
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
//运行结果
[root@localhost ku]# ./a.out 
8 6
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 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 6
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1

动态库优缺点:

优点:

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

缺点:

 1.当系统中多个应用程序都用了一个动态链接库,但是要求的版本不同,这时动态链接库之间就会相互干扰。
 2.性能开销。动态链接库为了做到“共享代码,但是不共享数据”,引入了不小的开销,调用动态链接库中的函数,需要好几次间接内存访问才能走到函数入口,全局数据也是。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452831.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

esrgan_ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks【阅读笔记】

针对SRGAN提出的几点改进&#xff0c;获得了PIRM2018视觉质量的第一名。首先是使用去掉BN层的Residual in Residual Dense Block作为网络的basic unit。并且使用residual scling 和 smaller initialization帮助训练更深的网络。第二点改进是使用了Relativistic Discriminator来…

PostgreSQL Frontend/Backend protocol (通信协议)

标签 PostgreSQL , protocol , proxy , 通信协议 背景 理解PostgreSQL的通信协议可以更好的开发类似SQL代理&#xff0c;SQL中间件&#xff0c;SQL防火墙&#xff0c;连接池等软件。 学习资料与软件 《PostgreSQL 读写分离代理 - Crunchy Proxy(base on golang)》 Postgres on …

启动FastDFS服务,使用python客户端对接fastdfs完成上传测试

1.启动tracker、storage、nginx服务&#xff1a; 启动fdfs_trackerd&#xff1a;sudo service fdfs_trackerd start 启动fdfs_storaged &#xff1a;sudo service fdfs_storaged start 启动Nginx&#xff1a;sudo /usr/local/nginx/sbin/nginx 注&#xff1a;此处给出重启服务…

软件工程方法学

传统方法学 传统方法学也称为生命周期方法学或结构化范型。它采用结构化技术(结构化分析、结构化设计和结构化实现)来完成软件开发的各项任务&#xff0c;并使用适当的软件工具或软件工程环境来支持结构化技术的运用。 面向对象方法学 与传统方法相反&#xff0c;面向对象方…

我做项目这些年的经验

1、中国充满大量非常敬业但不够职业的项目经理&#xff0c;不了解这一点&#xff0c;就做不好中国的项目。 2、真正的原因往往都隐藏在表面的理由背后。 3、做项目最高境界是和用户形成长期共生双赢关系。 4、卖功能&#xff0c;卖利益&#xff0c;卖服务&#xff0c;卖价值…

Python学习-终端字体高亮显示

1、采用原生转义字符序列&#xff0c;对Windows有的版本不支持&#xff08;比如win7&#xff09;&#xff0c;完美支持Linux 实现过程&#xff1a; 终端的字符颜色是用转义序列控制的&#xff0c;是文本模式下的系统显示功能&#xff0c;和具体的语言无关。 转义序列是以ESC开头…

Win32-Application的窗口和对话框

Win32 Application&#xff0c;没有基于MFC的类库&#xff0c;而是直接调用C接口来编程。 一、弹出消息窗口 &#xff08;1&#xff09;最简单的&#xff0c;在当前窗口中弹出新窗口。新窗口只有“YES”按钮。 int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstan…

Python面试题总结(4)--数据类型(列表)

1. 已知 AList [1,2,3,1,2]&#xff0c;对 AList 列表元素去重&#xff0c;写出具体过程。 答&#xff1a; AList [1,2,3,1,2] BList set(AList)print(BList) print(list(BList))输出结果&#xff1a; {1, 2, 3} [1, 2, 3]2. 如何实现 “1,2,3” 变成 [“1”,“2”,“3”…

项目团队要以十当一

如何建立起一支高效的团队&#xff0c;并有效的管理团队&#xff0c;一直是IT项目经理津津乐道的话题。任何一个IT项目经理对此都有自己一番不同的见解&#xff0c;根据自己团队特点&#xff0c;项目经理正在用自身独有的管理艺术改变着自己的团队。项目团队要以十当一&#xf…

Centos中配置环境变量

以Java的开发环境Jdk为例。 将jdk-9.0.1放置在/usr/local下&#xff08;UNIX规范&#xff09;&#xff0c;然后我们将jdk配置到环境变量中去。 $ mv jdk-9.0.1 /usr/local $ vim /etc/profile 修改 /etc/profile &#xff0c;最底部加入以下内容 export JAVA_HOME/usr/local/jd…

python面试题总结(5)--数据类型(字典)

1. 字典操作中 del 和 pop 有什么区别 答&#xff1a;del 可以根据索引&#xff08;元素所在位置&#xff09;来删除的&#xff0c;没有返回值。 pop 可以根据索引弹出一个值&#xff0c;然后可以接收它的返回值。 参考一 参考二 2. 按照字典的内的年龄排序 d1 [ {‘name’…

js下载文件 java_[Java教程]使用js实现点击按钮下载文件

[Java教程]使用js实现点击按钮下载文件0 2016-11-11 19:02:54有时候我们在网页上需要增加一个下载按钮&#xff0c;让用户能够点击后下载页面上的资料&#xff0c;那么怎样才能实现功能呢&#xff1f;这里有两种方法&#xff1a;现在需要在页面上添加一个下载按钮&#xff0c;点…

underscore.js源码研究(5)

概述 很早就想研究underscore源码了&#xff0c;虽然underscore.js这个库有些过时了&#xff0c;但是我还是想学习一下库的架构&#xff0c;函数式编程以及常用方法的编写这些方面的内容&#xff0c;又恰好没什么其它要研究的了&#xff0c;所以就了结研究underscore源码这一心…

人心散了、项目必然要败

最近接手一个项目&#xff0c;是从半路上接过来的。按照常理&#xff0c;只要脑子没被驴踢&#xff0c;是不会接人家的烂摊子的。我之所以接这个项目&#xff0c;一方面是因为这个项目中的开发人员是我部门的人&#xff08;本人是部门主管&#xff09;&#xff0c;另一方面是因…

国家自科委管文科学部认定的国内30种重要期刊

国家自科委管文科学部认定的国内30种重要期刊 A类刊物&#xff08;22种&#xff09; 1、管理科学学报&#xff08;双月刊&#xff09; 2、系统工程理论与实践&#xff08;月刊&#xff09; 3、管理世界&#xff08;月刊&#xff09; 4、数量经济技术经济研究&#xff08;月刊&a…

面向对象的四个要点

•把对象(object)作为融合了数据及在数据上的操作行为的统一的软件构件•把所有对象都划分成类(class)。•按照父类与子类的关系&#xff0c;把若干个相关类组成一个层次结构的系统。•对象彼此间仅能通过发送消息互相联系。

Django二次开发对接FastDFS

1.自定义文件存储器类 配置文件settings中加入如下配置 # 设置Django的文件存储类、&#xff08;名字固定&#xff09; DEFAULT_FILE_STORAGEutils.fdfs.storage.FDFSStorage# 设置fdfs使用的client.conf文件路径&#xff08;名字自己定义&#xff09; FDFS_CLIENT_CONF./util…

微信支付 java 集成案例_Spring Boot项目中集成微信支付v3

1. 前言最近忙的一批&#xff0c;难得今天有喘气的机会就赶紧把最近在开发中的一些成果分享出来。前几日分享了自己写的一个微信支付V3的开发包payment-spring-boot-starter&#xff0c;就忙里偷闲完善了一波。期间给微信支付提交了6个BUG&#xff0c;跟微信支付的产品沟通了好…

单挑力扣(LeetCode)SQL题:1308. 不同性别每日分数总计

相信很多学习SQL的小伙伴都面临这样的困境&#xff0c;学习完书本上的SQL基础知识后&#xff0c;一方面想测试下自己的水平&#xff1b;另一方面想进一步提升&#xff0c;却不知道方法。 其实&#xff0c;对于技能型知识&#xff0c;我的观点一贯都是&#xff1a;多练习、多实…