【linux深入剖析】动态库的使用(续) | 动静态库的链接


🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

在这里插入图片描述


目录

  • 回顾
  • 1. 打包库的使用
  • 2. 动态库可执行程序无法运行的问题
  • 3. 动态库可执行程序运行解决方法
    • 3.1 将库安装到系统中(/lib64/)
    • 3.2 环境变量LD_LIBRARY_PATH
    • 3.3 对库文件建立软链接
    • 3.4 ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
  • 4. 动静态库的链接


回顾

  • 回顾上节,我们在创建了动态库libmymath.so

在这里插入图片描述

  • 我们使用指令

gcc main.c -L. -lmymath
-L .(-L + 路径表示myc这个库在哪个路径下,这里就是用的点来代表当前路径,)
-lmymath(指明要链接mymath这个动态库)
因为gcc默认是调用的是C语言标准库,所以我们要在这里指明要使用我们的库

在这里插入图片描述

编译生成了文件a.out,运行程序是可以运行的

在这里插入图片描述

  • 使用ldd查看文件是否是调用的我们所创建的库

在这里插入图片描述

其实际链接的是/lib64/libc.so.6,这就是C语言标准库,同时也依赖了我们自己的库,libmymath.so

结论:编写库的人:未来要给别人(用这个库的人),交付的是:头文件+库文件。


我们想让别人使用我们的库就需要我们对其进行发布
将我们的库发布出来就是Makefile中output部分

  1 libmymath.so:add.o sub.o2     gcc -shared -o $@ $^3 .o:.c4     gcc -shared -c $<5 #add.o:add.c6 #   gcc -c -fPIC $< -o $@7 #sub.o:sub.c8 #   gcc -c -fPIC $< -o $@9 .PHONY:clean10 clean:11   rm -f *.o libmymath.so12 13 .PHONY:output                                                                                                                                                                           14 output:15 	mkdir -p ./mylib/mylib/15 	mkdir -p ./mylib/Headfile/15	 	cp -rf libmymath.so ./mylib/mylib/15	 	cp -rf add.h sub.h ./mylib/Headfile/15	 	tar -czf mylib.tgz mylib

output的工作就是帮我们在user目录下创建一个mylib的文件以及将我们的库拷贝过去,并且帮我们在user目录下创建一个Headfile的文件以及将我们的头文件拷贝过去,最后一步是打包文件

在这里插入图片描述

这里的mylib.tgz就是我们的库打包文件

  • 我们新建一个目录然后将打包文件移动到此目录下,实行解压,解压之后删除压缩包

在这里插入图片描述

这样我们要使用这个库就可以轻松使用了


1. 打包库的使用

接下来我们对其进行使用

  1. 我们将main.c主文件移动到该路径下进行编译

在这里插入图片描述

编译是无法运行的,这里缺少了头文件

  1. 我们使用指令gcc -o mytest main.c -I ./mylib/Headfile

-I + 路径是让编译器查找头文件时不仅在当前路径以及库路径查找也要在这个路径下进行查找
这样依然会报错,这是因为没有用到我们的库

  1. 我们使用指令gcc -o mytest main.c -I ./mylib/Headfile/ -L ./mylib/lib -lmymath链接到我们自己的库

在这里插入图片描述

运行出来了,就可以看到我们的mytest文件


我们上面这一长串也还是太长了,我们要想只链接一下我们的库就能编译怎么操作?

gcc -o mytest main.c -lmymath


解决办法:

  • 方法一:我们将库安装到系统的默认路径

所谓的把库(其他软件)安装到系统中,本质就是把对应的文件拷贝到系统指定的路径中

  1. 首先我们的系统默认头文件路径一般都在系统的include路径下

在这里插入图片描述

  1. 我们想拷贝到这个路径下需要我们提升权限,这些系统路径一般都是机器规定好的,都是root权限

在这里插入图片描述

  1. 系统默认的库路径在我们的lib64目录下

在这里插入图片描述
4. 拷贝库文件到默认库里

在这里插入图片描述

  1. 测试

在这里插入图片描述

但是在这里我们是不推荐将我们写的不成熟的库与头文件写入系统里的,所以这种方法是不推荐的


2. 动态库可执行程序无法运行的问题

我们如果不将库文件以及头文件移动到系统里,我们就还是只能采取我们的老办法,但是为什么我们生成的文件无法运行呢?
在这里插入图片描述

这里的报错说明了我们找不到这个目录


静态库在编译的时候是不会出现这个问题的,静态库的本质是从库里面把它的代码拷贝到这个程序当中,所以对静态库来讲,只要形成了可执行程序,静态库在后续就不需要再被使用了,所以在我们后续使用的时候就不会再出现查找静态库的任何动作

反而对动态库来讲,我们编译的时候是我们自己给它指明了我们的库路径,所以它编译成功了,但是形成文件之后,它再次找不到库了,这也就是动态库与静态库的差别

对于动态库:这里有两套路径

编译时的库搜索路径是给gcc的
运行时的库搜索路径是给OS的

也就是说我们在程序运行的时候也需要给它库的路径


回归正题,我们使用指令ldd来查看一下可执行文件的库路径
在这里插入图片描述
可以很清楚的看到,我们自己的库处于找不到的境地


3. 动态库可执行程序运行解决方法

我们有四种方法去解决这个问题

3.1 将库安装到系统中(/lib64/)

在这里插入图片描述

可以看到拷贝过去之后,我们的可执行文件的库再也没有出现not found,并且程序已经可以运行


3.2 环境变量LD_LIBRARY_PATH

环境变量LD_LIBRARY_PATH :系统运行程序时,动态库查找的辅助路径

在这里插入图片描述
系统默认在/lib64/路径下找,但是程序运行时不仅仅在/lib64/下找,也会在这个辅助路径下进行寻找,以冒号为分隔符,在目录下寻找

  • 我们将库的目录添加到环境变量LD_LIBRARY_PATH 里即可
    在这里插入图片描述

但是环境变量有一个缺点,那就是我们重启xshell之后,这个环境变量是会回到初始状态的


3.3 对库文件建立软链接

使用如下指令,我们在库文件里添加同名库文件软链接

sudo ln -s /home/cmj/work/newfile/mylib/mylib/libmymath.so /lib64/libmymath.so

在这里插入图片描述

我们再来运行,即可运行

在这里插入图片描述

3.4 ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

删除软链接,文件变为not fount状态
在这里插入图片描述

我们先来认识一下/etc/系统配置文件路径

在这里插入图片描述

这里面有一个/etc/ld.so.conf.d/
名称含义 ld是链接,so就是动态库,conf就是配置文件,.d就是指它是个目录

它是允许我们去配置各种各样的文件的,我们创建一个我们自己的配置文件cmj.conf,里面没有写任何东西
在这里插入图片描述

这个配置文件只需要我们写入我们需要其去识别的库路径就可以了
配置后需要我们更新环境变量的配置系统,用到指令 ldconfig

在这里插入图片描述
文件就重新成功运行了


4. 动静态库的链接

我们先实现动静态库全创建并帮我们打包的Makefile

  1 libmymath.a:add.o sub.o2     ar -rc $@ $^3     rm *.o4 %.o:%.c5     gcc -c $<6   7 libmymath.so:add.o sub.o8     gcc -shared -o $@ $^9 %.o:%.c             10     gcc  -c -fPIC $<11 #add.o:add.c        12 #   gcc -c -fPIC $< 13 #sub.o:sub.c14 #   gcc -c -fPIC $<                             15 .PHONY:clean16 clean:       17   rm -f -rf *.o libmymath.so *.a mylib mylib.tgz18                                                                                                                                                                                         19 .PHONY:output                     20 output:                           21         mkdir -p ./mylib/mylib/  22         mkdir -p ./mylib/Headfile/  23         cp -rf *.so ./mylib/mylib/24         cp -rf *.a ./mylib/mylib/25         cp -rf *.h ./mylib/Headfile/26         tar -czf mylib.tgz mylib
  • 依次输入指令

make
make libmymath.so
make output

在这里插入图片描述

  • 再将我们打包的压缩包文件传入user,user是我们假装的外部用户

在这里插入图片描述
我提供的既有静态库又有动态库。
我们将文件进行编译
输入指令

gcc -o mytest main.c -I ./mylib/Headfile/ -L ./mylib/mylib/ -lmymath

我们在最后并没有指明其使用动态库还是静态库,我们使用的是库的名字
在这里插入图片描述

最后我们可以看到我们动态库和静态库同时提供的时候,gcc默认使用的是动态库!!!

我们也可以指定使用静态库,在当初的库名后面加上-static即可
在这里插入图片描述


  • 我们将库里的动态库移到上级目录,再次运行该程序

在这里插入图片描述
我们可以发现它不依赖我们自己写的静态库

如果我们只提供的静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体式静态链接的


  • 我们将动态库移动回来,将静态库移除

在这里插入图片描述

我们尝试加-static

在这里插入图片描述如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错


结论:

  1. 如果我们同时提供动态库和静态库,gcc默认使用的是动态库
  2. 如果我们非要使用静态链接,我们必须使用的是动态库
  3. 如果我们只提供的静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体式静态链接的
  4. 如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错

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

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

相关文章

智能体Agent是AI时代普通人可参与的第一个红利机会

自从生成式 AI 兴起&#xff0c;掌握 prompt 能让 AI 工具更好为我们服务。而智能体的出现&#xff0c;让 AI 的使用门槛更是不断降低——都不用写 Prompt 了&#xff0c;直接用智能体就行了。 智能体Agent是AI时代普通人可参与的第一个红利机会© 由 ZAKER科技 提供 前几…

ActiveMQ 01 消息中间件jmsMQ

消息中间件之ActiveMQ 01 什么是JMS MQ 全称&#xff1a;Java MessageService 中文&#xff1a;Java 消息服务。 JMS 是 Java 的一套 API 标准&#xff0c;最初的目的是为了使应用程序能够访问现有的 MOM 系 统&#xff08;MOM 是 MessageOriented Middleware 的英文缩写&am…

4.9总结(Stream流,方法引用概述 || 乘法逆元,组合数)

Stream流 基本概念&#xff1a;以更简便的方式操作集合数据的形式&#xff1b; Steam流的操作步骤&#xff1a; 获取Stream流 中间方法&#xff1a;去重&#xff0c;跳过&#xff0c;获取&#xff0c; 过滤&#xff0c; 合并流&#xff0c;转换类型&#xff1b; 终结方法&…

2024-4-12-实战:商城首页(下)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业小结 作业 .bg-backward {width: 60px; height: 60px;background: url(..…

SpringMVC--02--上下文工具类(RequestContextHolder)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 RequestContextHolder背景1.RequestContextHolder的使用2.request和response怎么和当前请求挂钩?3.request和response等是什么时候设置进去的? 案例应用---用户信…

最新常见的图数据库对比,选型,架构,性能对比

图数据库排名 地址&#xff1a;https://db-engines.com/en/ranking/graphdbms 知识图谱查询语言 SPARQL、Cypher、Gremlin、PGQL 和 G-CORE 语法 / 语义 / 特性SPARQLCypherGremlinPGQLG-CORE图模式匹配查询语法CGPCGPCGP(无可选)1CGPCGP语义子图同态、包 2无重复边、包 2子…

C语言之九九乘法表||素数||最小公倍数

一、九九乘法表 &#xff08;1&#xff09;思路 1、九九乘法表中存在三个变量&#xff0c;以 x1 ; x2 ; y 为例&#xff08;这里也可以使用两个变量&#xff0c;用x1和x2来表示y&#xff0c;方法一样&#xff09; 2、想好了变量之后&#xff0c;我们要想怎样将他实现呢&#x…

智能售货机:引领便捷生活

智能售货机&#xff1a;引领便捷生活 在这个科技迅速进步的时代&#xff0c;便捷已成为生活的必需。智能售货机作为技术与便利完美结合的产物&#xff0c;正逐渐改变我们的购物方式&#xff0c;为都市生活增添新的活力。 智能售货机的主要优势是它的极致便利性。不论是在地铁…

变量---

一、变量概述 1、什么是变量 变量是用于存放数据的容器。通过变量名 获取数据&#xff0c;甚至数据可以修改。 变量的本质&#xff1a;变量是程序在内存中申请的一块用来存放数据的空间。 二、变量的使用 变量在使用时分两步&#xff1a;1、声明变量 2、赋值 三、变量语法…

【c 语言】结构体的定义格式及变量初始化

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

Vue2 —— 学习(三)

目录 一、绑定 class 样式 &#xff08;一&#xff09;字符串写法 1.流程介绍 2.代码实现 &#xff08;二&#xff09;数组写法 1.流程介绍 2.代码实现 &#xff08;三&#xff09;对象写法 1.流程介绍 2.代码实现 二、绑定 style 样式&#xff08;了解&#xff…

备忘录模式:恢复对象状态的智能方式

在软件开发中&#xff0c;备忘录模式是一种行为型设计模式&#xff0c;它允许捕获并外部化对象的内部状态&#xff0c;以便在未来某个时刻可以将对象恢复到此状态。这种模式是撤销操作或者回滚操作的关键实现机制。本文将详细介绍备忘录模式的定义、实现、应用场景以及优缺点。…

【linux深入剖析】深入理解基础外设--磁盘以及理解文件系统

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1.磁盘物理结构2.磁盘…

SpringAI初体验之HelloWorld

目录 前言1.准备工作2.初始化项目3.解决问题3.1 Connection Time out 连接超时问题3.2 You exceeded your current quota 额度超限问题 4.访问调用5.总结 前言 在逛SpringBoot页面时突然看到页面上新增了一个SpringAI项目,于是试了一下&#xff0c;感觉还行。其实就是封装了各家…

Harmony鸿蒙南向外设驱动开发-Audio

Audio驱动概述 多媒体系统是物联网设备开发中不可缺少的一部分&#xff0c;Audio作为其中重要的一个模块&#xff0c;Audio驱动模型的构建显得尤为重要。 本文主要介绍基于HDF&#xff08;Hardware Driver Foundation&#xff09;驱动框架开发的Audio驱动&#xff0c;包括Aud…

是时候开启Copilot下一篇章:Microsoft AI

微软总裁兼首席执行官萨提亚纳德拉欢迎 Mustafa Suleyman 和 Karn Simonyan 加入微软公司&#xff0c;领导一个新成立的部门 —— Microsoft AI&#xff0c;旨在开发 Copilot 和其他的面向消费者的 AI 产品和研究。 Mustafa Suleyman 将担任 Microsoft AI 执行副总裁&#xf…

基于单片机的智能居家火灾报警系统

摘要:采用STC15L2K32单片机设计了一种智能火灾报警系统,它是控制中心与多个不同功能的探测模块构成,实现了一个中心、多点辐射的火灾检测和报警功能。 关键词:智能居家,火灾报警系统,单片机,模块化设计。 0 引言 近些年电子技术、计算机技术为火灾报警系统和灭火系统在…

idea keymap用eclipse的相关快捷键

idea快捷键用eclipse的方式 CtrlShiftR 搜索文件 shiftshift 全部文件/类搜索 CtrlH 全局搜索 CtrlO 快速打开Outline大纲视图 ctrle 查看recent窗口文件 ctrlt 快速进入接口的实现类 ctrlshiftf 格式化代码 altshiftr 变量或函数的重命名 ctrlshifto 移除无用的头文…

YOLOv8绝缘子边缘破损检测系统(可以从图片、视频和摄像头三种方式检测)

可检测图片和视频当中出现的绝缘子和绝缘子边缘是否出现破损&#xff0c;以及自动开启摄像头&#xff0c;进行绝缘子检测。基于最新的YOLO-v8训练的绝缘子检测模型和完整的python代码以及绝缘子的训练数据&#xff0c;下载后即可运行。&#xff08;效果视频&#xff1a;YOLOv8绝…

C# WinForm —— 项目目录结构

1. WinForm 应用程序项目 Properties&#xff1a;属性文件夹存放了一个自动生成的类文件AssemblyInfo.cs&#xff0c;保存了一些应用程序集的一些信息引用存放了一些为应用程序提供所需的&#xff0c;某些功能的一些程序集&#xff08;dll文件&#xff09;等添加引用&#xff…