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

        学过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.mzph.cn/web/15764.shtml

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

相关文章

JS实现照片预览

以下是一个简单的JS代码示例&#xff0c;用于实现照片预览功能&#xff1a; <!DOCTYPE html> <html> <head><title>Photo Preview</title><script>function previewPhoto(event) {var reader new FileReader();reader.onload function(…

MySQL字符数据查询拆分

MySQL字符数据查询拆分 问题描述 数据表中某字段为特定单词组字符串&#xff0c;特定字符分隔。 现有需求&#xff1a;在不影响原始数据的情况下&#xff0c;查询显示拆分后的单词&#xff0c;方便后续对其进行后续操作。 演示 演示数据源 -- 测试表结构create table word_…

Java中创建不可变对象实现细节和例子

当我们在Java中创建不可变对象时&#xff0c;我们需要确保对象的状态在创建之后不能被修改。以下是一些具体的实现细节和例子&#xff0c;展示了如何在Java中创建不可变对象。 实现细节 使用final关键字&#xff1a; 类定义前使用final关键字&#xff0c;表示该类不能被继承&…

Mysql中的慢查询

Mysql慢查询的一些sql命令 慢查询的默认事件为10秒 #注意&#xff1a;慢查询一般是在调试阶段开启的&#xff0c;在开发阶段中一般不会开启&#xff0c;会对效率产生延误 #查询慢查询是否开启 show variables like %general%; #慢查询时间设置 show variables like long_query…

【运维项目经历|018】:Elasticsearch智能数据分析平台项目

目录 项目名称 项目背景 项目目标 项目成果 我的角色与职责 我主要完成的工作内容 本次项目涉及的技术 本次项目遇到的问题与解决方法 本次项目中可能被面试官问到的问题 问题1&#xff1a;本次项目周期&#xff1f; 问题2&#xff1a;服务部署架构方式及数量和配置&…

【简明指南:Python中的异常处理与稳健代码设计】

文章目录 前言异常处理基础捕获多种异常确保资源被释放使用else子句自定义异常结论 前言 软件开发过程中&#xff0c;保证代码的稳健性和可靠性至关重要。异常处理是实现这一目标的关键技术之一。在Python编程中&#xff0c;合理地捕获和处理异常不仅能提高程序的健壮性&#…

查找专利渠道

官方渠道 常规检索 (cnipa.gov.cn)https://pss-system.cponline.cnipa.gov.cn/conventionalSearch 佰腾网 佰腾网 - 查专利就上佰腾网_佰腾全球专利搜索平台_商标查询平台_企业工商信息查询平台 (baiten.cn)https://www.baiten.cn/

NLP(19)--大模型发展(3)

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 大模型训练相关知识&#xff1a; 问题&#xff1a; 数据集过大&#xff0c;快速训练模型过大&#xff0c;gpu跑不完 方案&#xff1a; 数据并行训练&#xff1a; 复制数据&#xff08;batch_size&#xff09;到多个gpu&…

簡述vue-router的動態路由

动态路由 addRoute 是 Vue Router 中的一个功能&#xff0c;它允许你在运行时动态地向路由表添加路由规则。这在一些需要基于用户行为或异步数据加载路由的场景中非常有用。以下是对 addRoute 功能的详细解释和使用示例&#xff1a; 1. 动态路由的概念 动态路由是指在应用运行…

[杂项]优化AMD显卡对DX9游戏(天谕)的支持

目录 关键词平台说明背景RDNA 1、2、3 架构的显卡支持游戏一、 优化方法1.1 下载 二、 举个栗子&#xff08;以《天谕》为例&#xff09;2.1 下载微星 afterburner 软件 查看游戏内信息&#xff08;可跳过&#xff09;2.2 查看D3D9 帧数2.3 关闭游戏&#xff0c;替换 dll 文件2…

精品PPT | MES设计与实践,业务+架构+实施(免费下载))

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 MES设计与实践 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&#x…

linux的chmod的数字太难记了,用u, g, o, a更简单!

u, g, o, 和 a是用来设置或查看文件或目录权限在类Unix或Linux系统中的特殊字符&#xff0c;它们分别代表文件或目录的所有者(user)、所属组(group)、其他用户(others)和所有用户(all users)。 而权限方r和w是其中的两种&#xff0c;分别代表读权限&#xff08;read&#xff0…

【探索数据结构】线性表之单链表

&#x1f389;&#x1f389;&#x1f389;欢迎莅临我的博客空间&#xff0c;我是池央&#xff0c;一个对C和数据结构怀有无限热忱的探索者。&#x1f64c; &#x1f338;&#x1f338;&#x1f338;这里是我分享C/C编程、数据结构应用的乐园✨ &#x1f388;&#x1f388;&…

Autodl服务器中Faster-rcnn(jwyang)复现(一)

前言 在做实验时需要用到faster-rcnn做对比,本节首先完成代码复现,用的数据集是VOC2007~ 项目地址:https://github.com/jwyang/faster-rcnn.pytorch/tree/pytorch-1.0 复现环境:autodl服务器+python3.6+cuda11.3+Ubuntu20.04+Pytorch1.10.0 目录 一、环境配置二、编译cud…

2024年软考总结 信息系统管理师

选择题 英文题&#xff0c;我是一题也没把握&#xff0c;虽然我理解意思。 千万不要认为考死记硬背不对。目的不在于这。工程项目中有很多重要的数字&#xff0c;能记住说明你合格。 案例 几乎把答案全写在案例中了。 计算题 今年最简单。没有考成本。 只考了关键路径&a…

头歌OpenGauss数据库-I.复杂查询第8关:两门及以上课程不及格的学生

任务描述 本关任务:根据提供的表和数据,查询两门及其以上不及格课程的同学的学号(s_id)、姓名(s_name)及其平均成绩(avg_score),要求计算平均成绩后为整数。 student表数据: s_ids_names_sex01Mia女02Riley男03Aria女04Lucas女05Oliver男06Caden男07Lily女08Jacob男c…

安卓开发:相机水印设置

1.更新水印 DecimalFormat DF new DecimalFormat("#"); DecimalFormat DF1 new DecimalFormat("#.#");LocationManager LM (LocationManager)getSystemService(Context.LOCATION_SERVICE); LM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2…

【学习笔记】计算机组成原理(七)

指令系统 文章目录 指令系统7.1 机器指令7.1.1 指令的一般格式7.1.2 指令字长 7.2 操作数类型和操作类型7.2.1 操作数类型7.2.2 数据在存储器中的存放方式7.2.3 操作类型 7.3 寻址方式7.3.1 指令寻址7.3.1.1 顺序寻址7.3.1.2 跳跃寻址 7.3.2 数据寻址7.3.2.1 立即寻址7.3.2.2 直…

第四十五天 | 322.零钱兑换

题目&#xff1a;322.零钱兑换 尝试解答&#xff1a; 1.确定dp[j]含义&#xff1a;装满容量为j的背包所需要放的硬币个数为dp[j]; 2.动态转移方程&#xff1a;dp[j] dp[j - coins[i]] 1; 3.遍历顺序&#xff1a;本题应该为组合类题目&#xff0c;不考虑装入的顺序&#x…

精品PPT | 精益生产管理中MES系统的实现与应用(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 MES系统的实现与应用 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&…