Linux之动静态库
今天我们来讲动静态库!
首先我们来粗粒度的划分一下动态库和静态库。
动态库就是只有一份库文件,所有想用该库的文件与改库文件建立链接,然后使用。这样可以提高代码复用率,避免重复拷贝产生没必要的内存消耗。
静态库,就是那个文件想用,就直接把库文件的内容拷贝过去,这样可以减少出现文件丢失的情况,略微提高运行速度,但是会造成巨大的空间消耗,大多数情况我们都选择动态库!

我们来通过写一个简单的计算器去探究动静态库。


首先我们看一下相关文件,至于具体的计算器实现代码太简单就不摆了。

这样我们得到所有的.o文件以后给别人就只需要把.o文件和代码丢给别人就可以了。
不需要一大堆之前的头文件,源文件了。
于是得到我们的第一个结论

然后我们再来学习静态库的生成。

然后如果我们直接链接就会报一堆错误!

这是因为gcc默认不认识第三方库文件,所以我们必须要指明文件!

但是我们发现仍然不行,原因是其真正的名字必须去掉lib和.a才行
然后-L.是表示在什么目录下(如果不加报错就加上)
-l是用来指明库名字。
![]()
如果是c标准库就不用加这些东西,所以我们以前从来没有加上过这些东西。
但是如果这个时候我们查ldd,发现查不到。也即ldd查的就是动态库的信息,静态库一单生成以后就在一起了,没有办法查了。

也就是gcc后面如果不加static那么静态库就直接静态链接,如果能动态链接就会动态链接。
加上以后则全部静态链接,否则直接报错!

然后为了方便我们以后交程序给别人,所以我们可以创建include,lib文件夹分别存放头文件和静态库!并且把相关文件拷贝进去。

就可以得到下面的库形式。

如果别人以后安装就可以直接把include文件拷贝到
下
lib就可以拷贝到
下!
然后这个时候再打包的时候再加上-I也即告诉gcc找头文件不仅要在当前目录找,系统目录找,也要到指定的目录进行寻找!!!
![]()
同理我们还要包括库文件,于是还要加上后面的语句去链接相关的库文件!
![]()
接下来我们来制作动态库!
与制作静态库的方法不同点是要加上-fPIC选项
具体含义后面解释!


然后shared含义也即把所有.o文件打包形成.so文件,但不是可执行程序!

在静态库的基础上进行修改即可!
![]()
然后正常进行链接即可,目前和静态库的使用没有任何区别。
但是如果我们想运行就会报错

其原因就是因为只告诉了编译器动态库在哪里,但是没有告诉操作系统动态库在哪里。(操作系统默认只在默认位置进行查找)
所有方法一:
然后我们直接添加头文件和库文件到操作系统默认位置,然后指明库进行链接即可!!!

![]()

方法二:建立软链接
我们在当前目录下建立一个软链接指向我们的库

同理我们也可以在我们的默认路径加上软连接也可以!

方法三:添加到环境变量里面
操作系统还会默认到下面环境变量包括的路径里面找!!!


方法四:直接更改系统配置文件
![]()
里面只要包含我们动态库的位置就可以了!!!

基本上这些方法就已经非常够用了,就不再多说!

如果我们就想连接静态库,那就加上-static
![]()
接下来我们讲如何使用外部库!
比如我们接下来就测试链接一个ncurses的库!

![]()
比如此处我就找了一个贪吃蛇的库,我们链接之后就可以通过了!!!
‘
然后我们就可以正常使用了!
以上就是如何使用别人的库!
接下来我们来讲动态库加载原理!!

在Linux系统下可执行程序的格式是ELF

1:首先我们要知道库和程序必须全部加载!

2:程序没有加载的时候也有地址!!!

首先我们要知道在编译成二进制的时候没有变量名和函数名了,而会被直接替换成地址!
而这些名字只是用来给人看的!机器是不看这些名字的!

所有程序在磁盘的时候已经具有了虚拟地址(也叫逻辑地址)!
一般是基地址加偏移量的方式。(0~FFFFFFFF)

调用函数的时候就是直接调用虚拟地址!
这种模式在Linux就被称为平坦模式!(编址过程中也是规则编址,方便使用)
于是这样内部函数的相对位置不变,加载到内存以后只要知道入口地址,那么就可以通过偏移量进行使用相应的函数和变量了!!!!!!!!
所有也即与位置无关码!
3:动态库加载到内存并且映射到共享区


这样库在内存就可以只加载一份了!!就可以大大节约空间了!
并且由于我们不能把指定加载到指定空间,所以我们需要

并且我们在可执行程序中调用函数的时候我们也只需要记录库地址和方法的偏移量即可!!
(首个虚拟地址)

所以我们只需要库加载之后,位置是确定的,我们之后就可以正常加载了!!!
只要库的位置不再改变!

于是我们就可以得出一个结论,我们在函数跳转的时候就是在地址之间跳转而已!

只不过平时我们只在正文处跳转,调用库函数的时候就要跳转到共享区而已!
至此,动静态库的内容也基本到尾!谢谢观看!
相关文章:
Linux之动静态库
今天我们来讲动静态库! 首先我们来粗粒度的划分一下动态库和静态库。 动态库就是只有一份库文件,所有想用该库的文件与改库文件建立链接,然后使用。这样可以提高代码复用率,避免重复拷贝产生没必要的内存消耗。 静态库…...
手机常亮屏不自动灭屏
一. 基础知识介绍 1. WakeLock(休眠锁) WakeLock用于保持设备的唤醒状态,有些情况下,即时用户不操作App,我们也需要保持屏幕处于唤醒状态,以保证用户体验,比如视频类APP和计步类APP,…...
JVM(1)基础篇
1 初始JVM 1.1 什么是JVM JVM 全称是 Java Virtual Machine,中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件。 Java源代码执行流程如下: 分为三个步骤: 编写Java源代码文件。 使用…...
相机图像质量研究(12)常见问题总结:光学结构对成像的影响--炫光
系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…...
[OPEN SQL] 删除数据
DELETE语句用于删除数据库表中的数据 本次操作使用的数据库表为SCUSTOM,其字段内容如下所示 航班用户(SCUSTOM) 需要删除以下数据 1.删除单条数据 语法格式 DELETE <dbtab> FROM <wa>. DELETE <dbtab> FROM TABLE <itab>. DELETE FROM &…...
C语言第二十五弹---字符函数和字符串函数(上)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 目录 1、字符分类函数 2、字符转换函数 3、strlen的使用和模拟实现 4、strcpy 的模拟实现 5、strcat 的模拟实现 6、strcmp 的模拟实现 7、strncpy 函数的使用 总结…...
寒假学习记录16:Express框架(Node)
后续会补充 1.引入express 1.先下载express框架 创建一个package.json格式的文件,里面写入 {"dependencies": {"express": "~4.16.1" //express版本号} } 然后打开终端输入 npm i 2.引入express模块 const express require(&quo…...
机器学习中的10种非线性降维技术对比总结
降维意味着我们在不丢失太多信息的情况下减少数据集中的特征数量,降维算法属于无监督学习的范畴,用未标记的数据训练算法。 尽管降维方法种类繁多,但它们都可以归为两大类:线性和非线性。 线性方法将数据从高维空间线性投影到低维空间(因此…...
[ubuntu]split命令分割文件
split 命令 $ split --help Usage: split [OPTION]... [INPUT [PREFIX]] Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default size is 1000 lines, and default PREFIX is x. With no INPUT, or when INPUT is -, read standard input.Mandatory argume…...
《小强升职记:时间管理故事书》阅读笔记
目录 前言 一、你的时间都去哪儿了 1.1 你真的很忙吗 1.2 如何记录和分析时间日志 1.3 如何找到自己的价值观 二、无压工作法 2.1 传说中的“四象限法则 2.2 衣柜整理法 三、行动时遇到问题怎么办? 3.1 臣服与拖延 3.2 如何做到要事第一? 3.…...
visual studio code could not establish connection to *: XHR failed
vscode远程连接服务器时,输入密码,又重新提示输入密码,就这样循环了好几次,然后会报上述的错误。由于我是window系统,我用cmd,然后ssh */你的IP地址/*发现可以远程到服务器上,但是通过Vscode就不…...
JVM-面试题
一、对象 1、对象创建 类加载检查 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池定位到类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。若没有,必须先执行类加载过程。分配内存 类加载检查通过后,jvm将为新生对象分配内存,…...
计算机网络——多媒体网络
前些天发现了一个巨牛的人工智能学习网站 通俗易懂,风趣幽默,忍不住分享一下给大家, 跳转到网站 小程一言 我的计算机网络专栏,是自己在计算机网络学习过程中的学习笔记与心得,在参考相关教材,网络搜素…...
GPIO八种工作模式
目录 一、推挽输出 二、开漏输出 三、复用推挽输出 四、复用开漏输出 五、浮空输入 六、上拉输入 七、下拉输入 八、模拟输入 GPIO八种配置模式,原理和使用场景,硬件原理如下图: 一、推挽输出 1、 原理 当控制栅极为低电平时&#x…...
C++初阶:适合新手的手撕list(模拟实现list)
上次讲了常用的接口:今天就来进行模拟实现啦 文章目录 1.基本结构与文件规划2.空参构造函数(constructor)3.完善迭代器(iterator)(begin(),end())4.List Capacity(size(),empty())4.增删改查(push_back,pop_back,pop_f…...
js手写Promise(上)
目录 构造函数resolve与reject状态改变状态改变后就无法再次改变 代码优化回调函数中抛出错误 thenonFulfilled和onRejected的调用时机异步then多个then 如果是不知道或者对Promise不熟悉的铁铁可以先看我这篇文章 Promise 构造函数 在最开始,我们先不去考虑Promi…...
基于Web技术的家居室内温湿度监测系统
设计一个基于Web技术的家居室内温湿度监测系统涉及前端和后端开发,以及与硬件传感器的集成。以下是一个简单的设计概述: ### 1. 系统架构 - **前端**: 用户界面,用于显示实时数据和历史记录,可通过Web浏览器访问。 - **后端**: 服…...
ubuntu22.04@laptop OpenCV Get Started: 009_image_thresholding
ubuntu22.04laptop OpenCV Get Started: 009_image_thresholding 1. 源由2. image_thresholding应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 重点分析3.1 Binary Thresholding ( THRESH_BINARY )3.2 Inverse-Binary Thresholding ( THRESH_BINARY_INV )3.3 Truncate Threshold…...
Zeek实战—快速构建流量安全能力
第1章 网络流量与网络安全 1.2流量与网络 从宏观角度进行观察,如果将计算机网络看作一个整体,可以很容易抽象出它是由以下3个部分组成的。 1.网络终端。指连接在网络中的、能够产生或消费网络流量的软/硬件系统,是网络流量在正常情况下的…...
vim命令编辑完文件后,按ESC键退出编辑模式,无法进入命令模式解决方案
发现问题 在Vim编辑器中,我们通常需要按Esc键来退出编辑模式并进入命令模式。但有时,你可能会发现即使按了Esc键,也无法进入命令模式。这可能是由于某些设置或插件导致的。不过,有一个解决办法可以帮助你解决这个问题。 解决办法…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
