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

news2025/8/10 7:53:53

🌈欢迎来到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.coloradmin.cn/o/33909.html

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

相关文章

sqli-labs/Less-54

这一关的欢迎界面提示我们可以进行10次尝试注入 但是10次以后就会重置各种信息其中就包括数据库、表格、字段等等 其次提示我们以id作为注入点 首先判断是否属于数字型注入 输入如下 id1 and 12 回显如下 这个回显印证了两件事情 一个是该注入类型不属于数字一个是能够使用联…

强吻雷佳音,公共场合整个身体倾斜头歪向吴京,倪妮这样做合适吗

做人难,做个名人更难。尤其是娱乐圈的明星,有人恨不得拿个放大镜,挖地三尺也要找出毛病。 著名演员倪妮,最近就遭遇了网络暴力,有人说她和吴京玩暧昧,公共场合把头歪向吴京一边。不知道是吃不着葡萄说葡萄酸…

【计算机视觉(CV)】基于高层API实现宝石分类

【计算机视觉(CV)】基于高层API实现宝石分类 作者简介:在校大学生一枚,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计…

RNN lstm

文章目录什么是RNNRNN工作原理图解多种RNN形态RNN的公式原理pytorch RNN 样例RNN实践lstm 案例踩坑 module ‘torchtext.data‘ has no attribute ‘Field踩坑 en_core_web_sm相关教程什么是RNN 阅读ytb视频莫烦: 什么是循环神经网络 RNN (深度学习)? What is Rec…

SpringBoot 引入 smart-doc 接口文档管理插件,以及统一接口返回

最近在将多个服务端项目的接口进行整合管理,原本使用的是Swagger接口文档管理插件,网上搜了一下类似的插件,发现这个smart-doc插件,似乎挺简约优雅的,而且还可以推送接口文档到Torna,进行统一管理&#xff…

2023-2028年中国硅碳负极材料行业市场预测与投资规划分析报告

本报告由锐观咨询重磅推出,对中国硅碳负极材料行业的发展现状、竞争格局及市场供需形势进行了具体分析,并从行业的政策环境、经济环境、社会环境及技术环境等方面分析行业面临的机遇及挑战。还重点分析了重点企业的经营现状及发展格局,并对未…

kafka学习(七):消息队列与JMS

1、消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。 1.1、消息队列有什么用? 消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统…

MCE | 神经元为胰腺癌细胞提供营养

胰腺导管腺癌 (PDAC) ,最常见的胰腺癌 (Pancreatic cancer) 类型 ,是最致命的实体肿瘤之一,具有很高的侵袭性。PDAC 治疗的不良预后与其独特而复杂的微环境和代谢可塑性有关。PDAC 的肿瘤微环境 (TME) 主要成分是细胞外基质 (ECM)、脉管系统、…

tensorflow2 MobileNet

简介 深度学习的发展伴随着模型参数的暴涨,导致对运行模型的设备有很大的限制,普通的卷积神经网络模型难以运用到移动或嵌入式设备中,主要是这些设备的内存有限,其次这些设备的算力不能满足足够的响应速度,即实时性差…

[附源码]java毕业设计疫情期间回乡人员管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Swin Transformer目标检测实验——环境配置的步骤和避坑

Swin Transformer1. 网上基础教程(带视频讲解)2. 配置虚拟环境时遇到的一些问题(按操作顺序排列)1. 网上基础教程(带视频讲解) 大家是不是都从b站来的呀,先给你们基础环境的配置和搭配的视频教…

【SQLite】三、SQLite 的常用语法

作者主页:Designer 小郑 作者简介:软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue、SpringBoot和微信小程序)、系统定制、远程技术指导。CSDN学院、蓝桥云课认证讲…

[论文阅读笔记18] DiffusionDet论文笔记与代码解读

扩散模型近期在图像生成领域很火, 没想到很快就被用在了检测上. 打算对这篇论文做一个笔记. 论文地址: 论文 代码: 代码 0. 扩散模型简述 首先介绍什么是扩散模型. 我们考虑生成任务, 即encoder-decoder形式的模型, encoder提取输入的抽象信息, 并尝试在decoder中恢复出来. 扩…

亚马逊鲲鹏系统:批量注册亚马逊买家号软件

之前我们有谈到过,想要注册亚马逊买家号,需要邮箱、ip、信用卡、收货地址和手机号。自己手动注册一个一个的太麻烦,还会花费大量的时间,那么有没有可以节约时间的自动化操作软件呢?想要自动化操作软件,来试…

金属带宽度测量方案

一、硬件部分 1.相机 像素:4864*3232 相机选择 1600 万像素即 4864*3232,即检测视场长宽比为 3:2 工件最大的直径为 320mm,假设检测的视场范围为 510*340 因 此 每 个 像 素 大 小 为 340mm/32800.104mm , 即 检 测 精…

数组形式的整数加法

1 问题 整数的 数组形式 num 是按照从左到右的顺序表示其数字的数组。 例如,对于 num 1321 ,数组形式是 [1,3,2,1] 。 给定 num ,整数的 数组形式 ,和整数 k ,返回 整数 num k 的 数组形式 。 2 方法 根据问题的描述…

ROS中使用protoBuf通信

ROS自身话题也挺好的,不过暂时还不知道如何判断网络,因此,还是想换回tcp/udp通信。 但是发现通信时数据比较多,调查一下,发现ROS支持google的protoBuf。 先建立一个ROS的项目,方便后面我们测试。 然后建立…

疫情物资储藏库建设规划问题,使用matlab+cplex+yalmib求解

疫情物资储藏库建设规划问题,使用matlabcplexyalmib求解一、Cplex安装及配置二、yalmib安装及配置三、案例分析一、Cplex安装及配置 一、安装Cplex Cplex 是一款商业化的规划问题求解器,支持python和matlab等常用语言,功能非常强大。可以根据…

19 0A-检索服务器支持的所有DTC的状态

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,19服务作为UDS中子功能最多的服务,一共有28种子功能,本文将介绍常用的19 0A服务:检索服务器支持的所有DTC的状态。此子功能不论DTC是否发生、状态如何,都让ECU返回所有…

1533_AURIX_TriCore内核架构_指令集信息

全部学习汇总: GreyZhang/g_tricore_architecture: some learning note about tricore architecture. (github.com) 学习的顺序有一点调整,切换到了内核的第二卷。先了解一下指令集的基本信息。第二卷主要就是讲指令集以及扩展的,而且基本上只…