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:动态库加载到内存并且映射到共享区

这样库在内存就可以只加载一份了!!就可以大大节约空间了!

并且由于我们不能把指定加载到指定空间,所以我们需要

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

(首个虚拟地址)

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

只要库的位置不再改变!

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

只不过平时我们只在正文处跳转,调用库函数的时候就要跳转到共享区而已!

至此,动静态库的内容也基本到尾!谢谢观看!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

京东购物拉新保姆级教程

您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦。💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通…

【Java多线程】Thread类的基本用法

目录 Thread类 1、创建线程 1.1、继承 Thread,重写run 1.2、实现 Runnable,重写run 1.3、使用匿名内部类,继承 Thread,重写run 1.4、使用匿名内部类,实现 Runnable,重写run 1.5、使用 lambda 表达式…

如何在30天内使用python制作一个卡牌游戏

如何在30天内使用python制作一个卡牌游戏 第1-5天:规划和设计第6-10天:搭建游戏框架第11-20天:核心游戏机制开发第21-25天:游戏界面和用户体验第26-30天:测试和发布附加建议游戏类型游戏规则设计界面设计技术选型第6-…

Qt:自定义信号,信号emit,传参问题,信号槽与moc

一、自定义信号,信号emit 1、自定义信号 在头文件中 加入signals: 就可以编写信号 2、emit emit的作用是通知信号发生 二、跨UI控件传参 每次按Dialog添加按钮主控件数字会增长 // .h private slots:void on_btnAdd_clicked(); signals:void sign…

Rust 数据结构与算法:5栈:用栈实现前缀、中缀、后缀表达式

3、前缀、中缀和后缀表达式 计算机是从左到右处理数据的,类似(A (B * C))这样的完全括号表达式,计算机如何跳到内部括号计算乘法,然后跳到外部括号计算加法呢? 一种直观的方法是将运算符移到操作数外,分离运算符和操…

【Java从入门到精通】Java变量命名规则

Java 变量命名规则 在 Java 中,不同类型的变量(例如实例变量、局部变量、静态变量等)有一些命名规则和约定。 遵循一些基本规则,这有助于提高代码的可读性和维护性。 以下是各种变量命名规则的概述: 使用有意义的名…

第13章 网络 Page733 “I/O对象”的链式传递 单独的火箭发射函数

把main函数中火箭发射代码挪走一些,构成一个单独的火箭发射函数launch_rocket(),如下图所示: 代码: 之所以没有将io_service对象也挪到launch_rocket()函数中,是因为正常的asio程序肯定还会有大量的其他异步操作需要这…

C++ 图上 bfs(五十八)【第五篇】

今天我们来学习一下图上bfs。 1.图上bfs 在图上,我们也可以进行 BFS,也可以解决图上 DFS 能解决的问题,比如连通块。 除此以外,根据 BFS 的性质,第一次到一个点的时候记下来的步数一定是到从起点到这个点的最小步数&…

Linux第56步_根文件系统第3步_将busybox构建的根文件系统烧录到EMMC

1、第1次将“rootfs”打包 1)、打开第1个终端,准备在“mnt”目录下创建挂载目录“rootfs”; 输入“ls回车” 输入“cd /mnt回车” 输入“ls回车”,查看“mnt”目录下的文件和文件夹 输入“sudo mkdir rootfs回车”,在“mnt”…

核心篇-OSPF技术之序(下)

文章目录 一. 实验专题1.1. 实验1:配置OSPF特殊区域1.1.1. 实验目的1.1.2. 实验拓扑图1.1.3. 实验步骤(1)配置IP地址(2)创建环回口(3)查看路由表(4)设置Stub区域&#xf…

(10)Hive的相关概念——文件格式和数据压缩

目录 一、文件格式 1.1 列式存储和行式存储 1.1.1 行存储的特点 1.1.2 列存储的特点 1.2 TextFile 1.3 SequenceFile 1.4 Parquet 1.5 ORC 二、数据压缩 2.1 数据压缩-概述 2.1.1 压缩的优点 2.1.2 压缩的缺点 2.2 Hive中压缩配置 2.2.1 开启Map输出阶段压缩&…

[OPEN SQL] 修改数据

MODIFY语句用于修改数据库表中的数据 MODIFY拥有INSERT和UPDATE的操作,如果数据库表中不存在符合条件的数据则会添加该条新数据,反之数据库表中存在符合条件的数据则会更新该条数据 本次操作使用的数据库表为SCUSTOM,其字段内容如下所示 航…

Mysql运维篇(四) Xtarbackup--备份与恢复练习

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。如有侵权,请留言,我及时删除! 前言 xtrabackup是Percona公司CTO Vadim参与开发的一款基于InnoDB的在线热备工具,具有…

力扣例题----二叉树

文章目录 1. 100.相同的树2. 572. 另一颗树的子树3. 266.翻转二叉树4. LCR 175.计算二叉树的深度5. 110.平衡二叉树6. 101. 对称二叉树7. 牛客题目:KY11 二叉树遍历8. 102.二叉树的层序遍历9. 236.二叉树的最近公共祖先10. 105.根据前序和中序构造一棵二叉树11. 106…

Rust - 切片Slice

Slice类型 Slice数据类型没有所有权,slice允许我们引用集合中一段连续的元素序列而不用引用整个集合。字符串slice(string slice) 是String中 一部分值的引用。如下述代码示例,不是对整个String的引用而是对部分String的引用: fn main() {l…

ESP32学习(1)——环境搭建

使用的ESP32板子如下图所示 它可以用Arduino 软件,基于C语言开发。但是,在这里,我是用Thonny软件,基于micro_python对其进行开发。 1.安装Thonny Thonny的软件安装包,可以去它官网上下载。Thonny, Python IDE for begi…

leetcode 160 相交链表

题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结…

09、全文检索 -- Solr -- SpringBoot 整合 Spring Data Solr (生成DAO组件 和 实现自定义查询方法)

目录 SpringBoot 整合 Spring Data SolrSpring Data Solr的功能(生成DAO组件):Spring Data Solr大致包括如下几方面功能:Query查询(属于半自动)代码演示:1、演示通过dao组件来保存文档1、实体类…

Flutter Android开发 梳理Google Material Design颜色体系

前言 做安卓开发(Kotlin语言),Flutter开发的人员应该都听说过谷歌一直推崇的Material Design,而Material Design Color是其推崇的颜色体系,具体来说,Material Design Color是一套旨在帮助设计师和开发者创…

树形dp 笔记

树的最长路径 给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。 现在请你找到树中的一条最长路径。 换句话说,要找到一条路径,使得使得路径两端的点的距离最远。 注意&…