Linux基础(七):Linux 系统上的库文件生成与使用

news2024/11/13 9:41:53

        学过C语言我们知道,C语言有标准库和自定义库,这些方便了我们的实际开发,提供了已经实现好的函数接口,我们使用的时候,只需要引入头文件即可,那具体的实现过程又是怎么样的呢?我们又该如何实现我们自己的库呢?这就是我们本节需要讲解的。

目录

一、什么是库文件

二、为什么需要库

三、静态库的生成与使用

3.1 自定义静态库的生成

3.2 自定义静态库的使用

3.3 将自定义的静态库移动到系统库目录下使用

3.4 静态库删除后是否可以使用

四、共享库的生成与使用

4.1 自定义共享库的生成

4.2 自定义共享库的使用

4.2.1  解决办法1

4.2.2  解决办法2

4.3 共享库删除后是否可以使用

五、静态库和共享库的区别


一、什么是库文件

        库是一组预先编译好的方法/函数的集合。 在 64 位的系统上有些库也可能被存储在/usr/lib64 下。 库有两种,一种是静态库,其命令规则为 libxxx.a,一种是共享库,其命令规则为 libxxx.so。如下图所示:

  1. Linux系统存储库的头文件(函数的声明)一般会被存储在 /usr/include
  2. Linux系统存储的库(函数的具体实现)的位置一般在:/lib 和 /usr/lib
  3. Linux系统存储的二进制可执行程序的位置在:/bin和/usr/bin

二、为什么需要库

         因为在引用外部方法时,不需要改动直接用就行,但给的是.c文件的话,使用要编译链接,很麻烦,所以直接生成.o文件,放到库里,使用的时候直接链接就好。库的隐蔽性较好,要让对方使用方法,但又不想让对象知道方法是如何让实现的,就可以用库。当同时有静态库和共享库时,优先使用共享库。

三、静态库的生成与使用

      这里展示实现自定义的静态库,以及如何使用,需要个3文件:add.c  max.c  foo.h,其中“foo.h”中是函数的声明,“add.c”和“max.c” 是函数的定义/具体实现

创建一个头文件,包含所有自定义函数的声明,后面再使用直接引|入自己创建的头文件即可!

3.1 自定义静态库的生成

第一步:先将需要生成库文件的所有“.c“文件编译成“.o”文件

第二步:使用 ar 命令将第一步编译的所有”.o”文件生成静态库,其中:c 是创建库  r 是将方法添加到库中    v 显示过程。

至此,静态库已经生成啦,是不是非常简单!注意:此时生成的静态库在当前目录下,并不是系统库文件位置,我们在下面使用的时候,要用双引号引入头文件即:#include '' foo. h'' 。

3.2 自定义静态库的使用

       上一小节,我们讲解了如何生成静态库,那么,我们又该如何使用呢?

静态库的使用也很简单,只需要在主函数文件里面引入我们自定义的静态库头文件,然后编译链接的时候,指定链接的静态库即可!

第一步:需要使用静态库的地方引入静态库对应的头文件 

第二步:编译链接的时候指定链接库的位置

3.3 将自定义的静态库移动到系统库目录下使用

         当我们测试完自己的库没有问题后,这时候便可以将自定义的静态库移动到Linux系统存储的库的位置:/lib 和 /usr/lib,移动完之后,它就成了标准库的一部分,后续我们的使用非常简单,在头文件的引入使用尖括号也可以了<>,此外,编译链接的时候,也不需要指定静态库的位置了,因为它首先回会到标准库位置下找,此时就可以找到。

3.4 静态库删除后是否可以使用

四、共享库的生成与使用

    这里展示实现自定义的共享库,以及如何使用,需要个3文件:add.c  max.c  foo.h,其中“foo.h”中是函数的声明,“add.c”和“max.c” 是函数的定义/具体实现

创建一个头文件,包含所有自定义函数的声明,后面再使用直接引|入自己创建的头文件即可! 

 

4.1 自定义共享库的生成

第一步:先将需要生成库文件的所有“.c“文件编译成“.o”文件

第二步:使用 gcc 命令将第一步编译的所有”.o”文件生成共享库 

       在共享库的创建过程中, -fPIC是一个编译选项,用于生成位置无关的代码。它告诉编译器生成与位置无关的代码,这对于共享库特别重要。共享库(也称为动态链接库)是一种在多个程序之间共享的库。当程序加载时,操作系统会将共享库映射到进程的地址空间中,以便程序可以调用库中的函数和访问库中的变量。位置无关的代码是一种在不同内存位置上执行时都能正常工作的代码。这对于共享库尤其重要,因为它们可能会在不同的内存地址空间中加载。-fPIC 选项使得编译器生成的代码能够在内存中的任何位置执行,而不受具体加载地址的限制。它通常用于创建共享库,以确保库能够在不同的进程中重定位到不同的内存地址,而不会发生冲突或错误。

至此,共享库已经生成啦,是不是非常简单!注意:此时生成的共享库在当前目录下,并不是系统库文件位置,我们在下面使用的时候,要用双引号引入头文件即:#include '' foo. h'' 。

4.2 自定义共享库的使用

       上一小节,我们讲解了如何生成共享库,那么,我们又该如何使用呢?

     共享库该如何使用呢?我们先学习下静态库的使用,然后观察是否可以使用,在主函数文件里面引入我们自定义的共享库头文件,然后编译链接的时候,指定链接的共享库的位置和库名。

第一步:需要使用静态库的地方引入静态库对应的头文件 

第二步:编译链接的时候指定链接库的位置  

        以下是使用共享库“libfoo.so”和“main.c”生成可执行文件的过程,其中 -L 指定库的 存储路径, -l 指定库的名称(不需要前面的‘lib’和扩展名‘.so’), 如果在库的存储路径有同名的共享库和静态库,gcc 默认使用共享库。

与静态库的使用对比,为什么这里会出现问题呢?又该如何解决呢?

这是因为:静态库和共享库在加载库时的行为是不同的
       1.静态库:静态库在链接时会被整体地复制到可执行文件中,因此可执行文件本身包含了静态库的代码和数据。当程序运行时,静态库的代码和数据已经被包含在可执行文件中,因此程序会直接调用其中的函数或访问其中的变量,而不需要额外加载库文件。因此,静态库在运行时不会去查找库文件,而是直接使用可执行文件中已经包含的库代码和数据。

         2.共享库:共享库在程序运行时才会被加载到内存中。程序在启动时会查找共享库,并将其加载到内存中的地址空间。通常,操作系统会预定义一些标准位置用于查找共享库,比去存储库的标准位置(/lib 或/usr/lib 等)加载。程序在运行时会根据操作系统的规则去这些标准位置下查找共享库。如果共享库不存在于这些位置,那么程序可能会因为找不到库而报错。
       总的来说,静态库在链接时就已经被包含在可执行文件中,程序运行时不需要额外查找库文件;而共享库在运行时才会被加载到内存中,程序会按照操作系统的规则去标准位置下查找共享库。

4.2.1  解决办法1

既然,共享库会去标准位置下找对应的库,那我们就可以将共享库移动到标准库位置下,这样就不会报错了。

4.2.2  解决办法2

如果库不在标准位置下,我们放在当前位置下,也可以通过设置环境变量”LD_LIBRARY_PATH”来指定加载库的路径,这样也就不会报错了。

ldd命令可以查看当前可执行程序依赖哪些库 

4.3 共享库删除后是否可以使用

       共享库只有在运行的时候,才会去标准库位置下去找对应的库,不会进行拷贝,因此删除后,可执行程序无法运行,共享库只有一份,静态库会被拷贝到可执行程序里面,因此删除后还可以使用。

五、静态库和共享库的区别

        静态库在链接时将用到的方法包含到最终生成的可执行程序中,成为可执行程序的一部分,而共享库不包含,也就是说可执行程序里面是没有实现的方法的,只做标记,在运行程序时,才动态加载。

静态库:

       用静态库编译出来的程序,相当于是把静态库里的.o文件拷贝了一份到可执行程序里,因此即使将库里的文件删除,可执行程序依然能执行。如果库里的数据需要更新,但原来库里的.o文件已经成为了可执行程序的一部分,此时要用更新的方法,就要把可执行程序删除,重新编译链接一个新文件。因此,静态库删除后,可执行程序仍然可以正常使用

共享库:

       用共享库编译出来的程序,相当于是标记了所需方法,但可执行程序里没有所需方法的实现,因此当所需方法在库里删除后,可执行程序找不到所需方法,文件就运行不了。

共享库里的数据更新,可执行程序,在运行时直接寻找共享库,就直接能用更新后的.o文件。因此,共享库删除后,可执行程序无法正常使用!

以上就是全部内容!请务必掌握,这是后续学习的基础,欢迎大家点赞加关注评论,您的支持是我前进最大的动力!下期再见!

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

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

相关文章

[7] CUDA之常量内存与纹理内存

CUDA之常量内存与纹理内存 1. 常量内存 NVIDIA GPU卡从逻辑上对用户提供了 64KB 的常量内存空间&#xff0c;可以用来存储内核执行期间所需要的恒定数据常量内存对一些特定情况下的小数据量的访问具有相比全局内存的额外优势&#xff0c;使用常量内存也一定程序上减少了对全局…

Java进阶学习笔记24——Object类

Object类: Object类是Java中所有类的祖宗类&#xff0c;因此&#xff0c;Java中所有类的对象都可以直接使用Object类中提供的一些方法。 所有类都是Object类的子孙类。 API文档&#xff1a; Object类的成员方法&#xff1a; Object类的常见方法&#xff1a; Student类&…

python冰雹序列的探索与编程实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、冰雹序列的奥秘 二、编程实现冰雹序列 三、测试与验证 四、总结与展望 一、冰雹序列的…

pycharm配置python开发环境—miniconda+black+gitlab

下载miniconda管理python开发环境 miniconda下载地址&#xff1a;https://docs.anaconda.com/free/miniconda/ miniconda最新版本的python版本是python3.12.2&#xff0c;下载这个miniconda最新版本后&#xff0c;会导致执行conda create -n py31013 python3.10.13指令配置py…

基于STM32实现智能水族箱控制系统

目录 引言环境准备智能水族箱控制系统基础代码示例&#xff1a;实现智能水族箱控制系统 水温传感器数据读取水泵与加热器控制水位传感器数据读取用户界面与显示应用场景&#xff1a;水族箱管理与环境控制问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌…

力扣刷题---2283. 判断一个数的数字计数是否等于数位的值【简单】

题目描述 给你一个下标从 0 开始长度为 n 的字符串 num &#xff0c;它只包含数字。 如果对于 每个 0 < i < n 的下标 i &#xff0c;都满足数位 i 在 num 中出现了 num[i]次&#xff0c;那么请你返回 true &#xff0c;否则返回 false 。 示例 1&#xff1a; 输入&a…

C++面向对象程序设计 - 输入和输出

程序的输入指的是文件将数据传送给程序&#xff0c;程序的输出指的是从程序将数据传送输出文件。 C的输入和和输出包括以下三个方面&#xff1a; 对系统指定的标准设备的输入和输出&#xff0c;即从键盘输入数据&#xff0c;输出到显示器屏幕。以外存磁盘&#xff08;或光盘、…

消费者相关高效读写ZK作用

消费者分区分配策略 目录概述需求&#xff1a; 设计思路1.消费者分区分配策略2. 消费者offset的存储3. kafka消费者组案例4. kafka高效读写&Zk作用5. Ranger分区再分析 实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show …

学习存储协议的利器,聊聊tcpdump和Wireshark

数据存储技术分为多个方面,包括数据持久化、数据映射、数据压缩和通信协议等等。其中通信协议是数据存储技术中非常重要的一部分,正是通信协议使得计算节点可以访问存储设备。同时,也正是不同的协议让存储系统呈现不同的形态。 如下图所示,通过iSCSI协议,可以将存储端的存…

解决Vue3+TS+vite,VSCode 高亮语法错误

一般像这种提示&#xff0c;有可能就是TypeScript语法的识别问题&#xff0c; 一般我们重装一下Vue - Official插件 或者将tcconfig.json中的moduleResolution改为node模式&#xff0c; 基本都是TypeScript无法识别vue文件中的TypeScript语句导致的

22款奔驰GLE450升级原厂AMG阀门运动排气声浪

提升车辆外观&#xff1a;空气悬挂系统可以调节车辆的高度&#xff0c;使车身更接近地面或提高离地间隙&#xff0c;从而改变车辆外观&#xff0c;增加个性化和独特性。 改善驾驶舒适性&#xff1a;空气悬挂系统具有更好的减震效果&#xff0c;可以提供更舒适的驾驶体验&#…

Ant design vue的表格双击编辑功能(即双击开始编辑并自动获得焦点,失去焦点时完成编辑)

本文基于Ant Design Vue官方网站的表格&#xff08;可编辑单元格&#xff09;&#xff08;表格 Table - Ant Design Vue (antdv.com))中的样板代码获得双击编辑且获得焦点、失去焦点时完成编辑的功能。 要点&#xff1a; &#xff08;1&#xff09;双击时候实现编辑&#xff…

docker同步bilibili收藏视频到群晖,可配合emby

作者是amtoaer&#xff0c;在github项目地址&#xff1a;https://github.com/amtoaer/bili-sync 有两个版本&#xff0c;1.0和2.0&#xff0c;我使用的是2.0 PS2&#xff1a;2.0和1.0版本目录结构不兼容&#xff0c;所以部署后会全量重新下载视频。 演示&#xff1a; 依然是…

解析售后维修服务平台如何助力企业高效运营与决策

随着生活质量的不断提高&#xff0c;人们对于售后服务的要求也越来越多。因此&#xff0c;售后服务已经成为企业竞争力的重要组成部分。售后服务平台作为连接企业与消费者的桥梁&#xff0c;不仅关乎着消费者的满意度&#xff0c;而且直接影响着企业的品牌形象与市场地位。那么…

用实践结果告诉你为啥说 CloudFlare 是赛博菩萨?

最近几天明月都没有更新博客了,主要是接了几个 CloudFlare 代维配置的活儿,有需要加速优化的,有需要排除疑难故障的,有需要提高防御攻击能力的甚至还有纯粹为了体验“打不死”装逼需要的。总之,各种各样的需求,五花八门的,好在 CloudFlare 都能一一满足,最主要的是这些…

VBA技术资料MF157:创建每个标题的目录

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

(Java面试题分享)万里长征-03-搜狐

万里长征-03-搜狐 ⚙ 以下内容基于GPT-4o模型 问题 1.LeetCode103 二叉树的锯齿形层序遍历 103. 二叉树的锯齿形层序遍历 - 力扣&#xff08;LeetCode&#xff09; 2.LeetCode5 最长回文子串 5. 最长回文子串 - 力扣&#xff08;LeetCode&#xff09; 3.Kafka为何那么快 …

Leetcode刷题笔记3:链表基础1

导语 leetcode刷题笔记记录&#xff0c;本篇博客记录链表基础1部分的题目&#xff0c;主要题目包括&#xff1a; 203.移除链表元素707.设计链表206.反转链表 知识点 链表 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据…