【Linux】基础IO —— 动静态库的制作与使用

news/2024/5/2 17:10:32/文章来源:https://blog.csdn.net/qq_42996461/article/details/127984712

🌈欢迎来到Linux专栏~~动静态库的制作与使用


  • (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort
  • 目前状态:大三非科班啃C++中
  • 🌍博客主页:张小姐的猫~江湖背景
  • 快上车🚘,握好方向盘跟我有一起打天下嘞!
  • 送给自己的一句鸡汤🤔:
  • 🔥真正的大师永远怀着一颗学徒的心
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
  • 🎉🎉欢迎持续关注!
    在这里插入图片描述

请添加图片描述

动静态库的制作与使用

  • 🌈欢迎来到Linux专栏~~动静态库的制作与使用
    • 一.动态库 & 静态库
    • 二. 制作静态库
      • 🌈制作(编写者角度)
      • 🌈使用(使用者角度)
    • 三. 制作动态库
      • 🥑制作
      • 🥑使用
    • 为什么要有库?
    • 总结一下
  • 📢写在最后

请添加图片描述

一.动态库 & 静态库

可能大家都快要忘记了这方面的知识,下面来复习一下 ,也可以来看看这篇博客->🔥动静态库🔥
在Linux中,一般库分为两种:动态库和静态库,它们就是文件!

  • 静态库 :库文件以.a为后缀
  • 动态库 :库文件以.so为后缀

库文件的命名规则:libname.so 或者 libname.a [.后面可能跟其他的内容]

库的真实名字掐头去尾就是库名称。即去掉lib前缀并去掉.so/.a后缀,如上文中的c库

(在windows中,动态库以.lib为后缀,静态库以.dll为后缀)

我还记得gcc在编译的时候动态链接编译的,如果需要静态链接编译 则要带-static

在这里插入图片描述

可以观察到动态链接时文件体积较小,静态链接时文件体积较大。
原因很简单嘛,静态链接是把库文件的有关代码拷贝到我的可执行文件中,因此生成的文件比较大,可移植性较好。而动态链接,是在程序执行时由运行时链接文件加载库(地址),这样可以节省内存和硬盘的空间

我们买的云服务器没有内置语言的静态库,而只有动态库,需要yum安装C/C++静态库

sudo yum install glibc-static
sudo yum install libstdc++-static

二. 制作静态库

问了一个小问题:库里面要不要main函数呢?

  • 答案是不能有,库是给别人用的,两个main函数会冲突

准备工作:在这里插入图片描述

不出意外,编译成功了

在这里插入图片描述
但库的制作只是这么简单?这还远不能称为制作库

我们知道编译时,只要把源文件编译成.o文件,再将其链接起来成为一个可执行程序

在这里插入图片描述

这下问题来了,我只把编好的.o.h给人家,别人能用吗?

答案是:可以的

在这里插入图片描述

但是如果.o文件过多呢?
我们可以把一堆.o文件以某种方式打包,这种过程叫做形成

🌈制作(编写者角度)

mklib目录下写这样一个Makefile ~

在这里插入图片描述

💦 1. 将库文件全部编译为.o

💦 2. 再用ar命令,把所有的.o打包在一起

可是怎么样打包呢?

ar -rc libname.a [待打包.o] 
//举例:
ar -rc libhello.a mymath.o myprint.o
  • ar是gnu的归档工具(Archive files),相当于打包成指定名称的文件

  • rc表示replace and create

hello库 —— include(包含库的所有头文件) —— lib (包含对应的库文件)

在这里插入图片描述

在这里插入图片描述

这样就打包了库

🌈使用(使用者角度)

立即把装好的库,拿来用一下

在这里插入图片描述

编辑main.c的时候发现一大堆错误

在这里插入图片描述

这下咋搞呢?

  1. 库的安装把头文件和库文件拷贝进系统中不建议:第三方库没经过测试,会污染其他的头文件)
    头文件 gcc的默认搜索路径是 : /usr/include;库文件的默认搜索路径是: /lib64 or /usr / lib64
  2. 硬使用显性的告诉编译器各种文件在哪
    在这里插入图片描述
    因为不在当前路径上,也不在库上,所以搜索不到

🌍直接编译会报错:找不到头文件。那当然找不到,编译器并不会查找你同级目录下目录中有啥, 因此要带-I./lib,指明在当前目录下的lib目录下找;

🌍又报错说找不到库函数的实现,因此带-L./lib,要告知库路径在哪儿

🌍但是实际情况可能有很多库,编译器也不知道链接这个路径下哪个库,因此同时要指定库。
-lhello(-l+库名)

在这里插入图片描述

  • -I:指明头文件搜索路径
  • -L: 指明库文件搜索路径
  • -l: 指明要链接哪个库

三. 制作动态库

🥑制作

🎨还是要将库文件全部编译为.o,只不过要带选项-fPIC,形成与位置无关码

gcc -fPIC -c mymath.c -o mymath.o

什么叫做与位置无关的目标二进制文件呢?
静态库使用的是绝对编址,动态库采用相对编址(段地址 + 偏移),无需精准的地址

举个例子:
在这里插入图片描述

🎨 要把库打包,我们不再使用ar命令,记得带选项-shared告诉gcc形成动态库了而不是可执行程序

gcc -shared myprint.o mymath.o -o libhello.so

在这里插入图片描述

🎨接下来就是在makefile形成库并且打包发布的过程,形成动态库和静态库

在这里插入图片描述

🥑使用

tar打包 发到网上

tar czf mylib.tgz output

在这里插入图片描述

🌊同样的我们需要指定路径搜索头文件-I./lib,同样的也需要指明库文件的搜索路径-L./lib,同样的也要指明链接哪个库

gcc main.c -I output/include -L output/lib -lhello

在这里插入图片描述

编译器默认的就是动态链接

  • 如果是只有静态库,就会把静态库拷贝进a.out中,gcc只能对该库进行静态链接
  • 如果动静态库同时存在,默认就用动态库
  • 如果我就想用静态库:-static摒弃默认优先使用动态库的原则,使用静态库

但是一运行./a.out就报错了。因为静态库把目标模块直接拷贝进去,运行时不需要再找;而动态库,编译时需要找,运行时也需要加载动态库

**在这里插入图片描述**静态库文化和本身的代码是放在了一起的;如果有重复的进程要调用,动态库:直接建立页表与内存的映射关系,也就可以跳转访问了;所以动态库加载一次就可以被多个进程所共同使用静态库多少次调用就有多少个拷贝,如果是十个一样的程序调用,那可能有9个是重复的

可是刚刚我编译时不是已经告诉了库路径了吗?为什么还是说我找不库? 奇怪

⚡但这只是告知了编译器gcc头文件库路径在哪里,当程序编译完成后,已与编译器无关,运行的时候加载器还是不知道它们在哪儿(所以报错)

也就是形成了a.out后,要和系统说动态库在哪

✨ 于是 —— 咱们需要在运行时前一步告知系统库在哪,有这样4种常见做法:

  1. 动态库头文件拷到共享库路径/lib64下(强烈不建议,污染)

  2. 通过导入LD_LIBRARY_PATH这个环境变量,指明程序启动后动态库的搜索路径(最推荐的)

    在我们的服务器一般是空空如也的 —— 接下来我们导入进去

export LD_LIBRARY_PATH=路径 	#导入环境变量

在这里插入图片描述
当然了,这种在命令行设置的环境变量,只在本次会话有效,退出登陆后再进来就没了。

  1. 如果想让环境变量永久生效,可以把它添加到登陆的启动脚本里(强烈不推荐
    比如vim ~/.bash_profile或者vim ~/.bashrc

  2. 修改系统文件:配置系统文件/etc/ld.so.conf.d/,是系统搜索动态库的路径,这种做法可以永久生效

    在这里我们打开任意一个看看,其中也不过是一个配置路径

    我们需要以sudo提升权限 进入:①添加配置文件,②在其中添加库的搜索路径,③并更新缓存。

在这里插入图片描述
然后我们执行,更新配置文件的缓存

ldconfig	 //更新库路径缓存

后面就开始生效了(再次登录也有效)

在这里插入图片描述

如果你把这配置文件删了,那当然又不行了

[root@VM-24-5-centos ld.so.conf.d]# rm oneManBand.conf
[root@VM-24-5-centos ld.so.conf.d]# ldconfig

我们还是推荐添加环境变量的,虽然麻烦点,但是为了后面熟悉上手

为什么要有库?

  1. 使用库的角度站在巨人的肩膀上,库的存在可以大大减少我们开发的周期,提高软件本身的质量
  2. 写库人的角度: 1.简单 2. 代码安全(不暴露底层代码)

总结一下

📢写在最后

基础IO总算完结了,进程通信我来了

在这里插入图片描述

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

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

相关文章

Spring Boot 检索定时任务

概述 应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持。 Elasticsearch是一个分布式搜索服务,提…

Unity3D占用内存太大怎么解决呢? -下

什么时候才是UnusedAssets?看一个例子: Object obj Resources.Load("MyPrefab"); GameObject instance Instantiate(obj) as GameObject; ......... Destroy(instance); 创建随后销毁了一个Prefab实例,这时候 MyPrefab已经没有被实际的物体…

5.XMLHttpRequest对象

XMLHttpRequest简称xhr,是浏览器提供的Javascript对象。之前我们使用的都是jQuery中的Ajax,现在我们使用原生JS的Ajax 目录 1 GET请求 1.1 不带参数请求 1.2 带参数请求 2 URL的编码与解码 2.1 编码 encodeURI() 2.2 解码 decodeURI() 3 …

【通用设计方法】之接收异常保护

目录 前言 一、接收异常保护 二、超短包、背靠背的支持 后记 前言 为了系统的鲁棒性,我们常常会做一系列的异常保护功能,避免系统挂死。 这里仅仅介绍接收保护的某些设计思路,抛砖引玉。 一、接收异常保护 设计思路:通过可配…

数据可视化大屏设计

在数据业务展示场景中,数据可视化大屏已经变得十分常见。那么在设计思路上,数据可视化大屏应当遵循什么样的设计逻辑?本篇文章里做了介绍,一起来看一下。 一、数据大屏的应用场景 1、大型会议 2、业务展示 二、数据大屏分类 1、展…

C语言源代码系列-管理系统之会员计费系统

往期文章分享点击跳转>《导航贴》- Unity手册,系统实战学习点击跳转>《导航贴》- Android手册,重温移动开发 👉关于作者 众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过…

【Python百日进阶-WEB开发-冲進Flask】Day183 - Flask数据库ORM基础、增加

文章目录一、day03项目环境和结构搭建1.1 flask-script1.1.1 flask-script是干什么的?1.1.2 flask-script安装1.1.3 flask-script的使用1.1.3.1 创建Manager实例1.1.3.2 初始化实例出错与解决1.1.4 终端启动1.1.4.1 查看runserver参数1.1.5 自定义添加manager命令1.…

linux篇【11】:linux下的线程<前序>

目录 一.linux下的线程 1.linux下的线程概念 (1)教材上粗略的 线程 定义 (2)线程的引入 (3)线程真正定义 以及 示意图 (4)linux 和 windows等其他操作系统的线程对比 &#xf…

新的趋势:From Big to Small and Wide data

新的趋势:From Big to Small and Wide data 所以,在这个时候,作为率先提出要做 MySQL 开源 HTAP 数据库的 StoneDB,想要稍微冷静一下。 不是说我们不做 HTAP 了,而是有了一个新的思路。这个思路,也同样来…

【亲测】网址引导页管理系统

介绍: 易航网址引导系统-网址引导页管理系统去授权版一款极其优雅的易航网址引导页管理系统, 如果有问题可以跟我反馈,共同进步。祝各位道友一路飞升,顶峰相见!内置12套模板和防墙插件。 项目亮点: 1、…

Redis基础命令(String类型)Value为JSON

目录 String类型(存储的值为JSON形式) 问题: 解决办法: 示例: 实际操作: 总结: String类型(存储的值为JSON形式) 问题: Redis没有类似MySql中的表的概…

2022年戈登·贝尔奖授予等离子体加速器突破研究

ACM 总裁Cherri Pancake(图片来源:网络) 11月17日,在达拉斯举行的SC22颁奖典礼上,ACM将2022年戈登贝尔奖(Gordon Bell Prize)授予了一组研究人员,他们利用四台超级计算机&#xff08…

【Flink】基本转换算子使用之fliter、flatMap,键控流转换算子和分布式转换算子

文章目录一 Flink DataStream API1 基本转换算子的使用(1)flitera 使用匿名类实现b 使用外部类函数实现b 使用flatMap实现(2)flatMapa 使用匿名类实现b 使用匿名函数实现2 键控流转换算子(1) keyBy&#xf…

中国互联网众筹行业

近些年,中国互联网发展迅速,众筹这种起源于美国的新型互联网金融模式更是一直处于风口浪尖。在“大众创业、万众创新”的背景下,这种低门槛的融资模式也深受欢迎,加上阿里、京东、苏宁三大电商的巨头的相继入场,更令这…

IMS各网元的主要功能

文章目录用户注册时: 手机发出一个注册消息到他所在的拜访地的P。 比如,他是山西太原的用户,他这时候到了北京,那么这个时候,他要注册到IMS网络里面的话,这个P-CSCF就是北京的P-CSCF,这个北京的…

CAS号:376364-38-4,rCRAMP (rat)

rCRAMP (rat) 是一种大鼠组织蛋白酶相关的抗菌肽,有助于大鼠脑肽/蛋白质提取物的抗菌活性。rCRAMP (rat) 是大鼠中枢神经系统先天免疫系统的关键参与者。rCRAMP (rat) is the rat cathelin-related antimicrobial peptide. rCRAMP (rat) contributes to the antibac…

Kotlin 开发Android app(十一):Android控件RecyclerView

Android 中的控件非常的丰富,我们会陆陆续续的进行介绍,从第九节开始,关于Kotlin 的语法特性就差不多结束,后面如果有发现需要说明的语法,再进行相关的补充。 在Android的控件中,RecyclerView算是一个大控…

从 Uber 数据泄露事件我们可以学到什么?

Uber 数据泄露始于一名黑客从暗网市场购买属于一名 Uber 员工的被盗凭证。最初尝试使用这些凭据连接到 Uber 的网络失败,因为该帐户受 MFA 保护。为了克服这一安全障碍,黑客通过 What’s App 联系了 Uber 员工,并假装是 Uber 的安全人员&…

OA系统,有效提升企业办公效率落实执行力

企业管理的成功将最终取决于企业的执行情况,只要有良好的经营管理,管理系统,一个好的领导者,充分调动员工的积极性,将能最大限度的管理执行力。 OA协同办公系统提供了工作流和协同工作互补结合。工作流程严格规定了工作…

大数据面试题(四):Yarn核心高频面试题

文章目录 Yarn核心高频面试题 一、简述Hadoop1与Hadoop2的架构异同 二、为什么会产生yarn,它解决了什么问题,有什么优势? 三、HDFS的数据压缩算法?及每种算法的应用场景? 1、gzip压缩 2、Bzip2压缩 3、Lzo压缩 …