动静态库以及动态链接

文章目录

  • 静态库
    • 制作静态库
    • 如何使用静态库
  • 动态库
    • 动态库的制作
    • 动态库的使用
    • 动态链接

库是给别人用的,所以库中一定不存在main函数。库一般会有lib前缀和后缀,去掉前缀和后缀才是库名

静态库

静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。

库制作的本质就是把库中的源文件全部翻译成.o目标二进制文件,然后打包。
Linux中可以使用 gcc -c 选项将源文件翻译成.o文件。

制作静态库

制作静态库就只需要把所有的.h文件给用户,.h就相当于使用说明书,然后再把我们打包好的静态库,把他们放到一起给用户就可以了。
在这里插入图片描述
静态库打包可以用ar命令,可以使用Makefile。

插入图片描述](https://img-blog.csdnimg.cn/direct/1b468975a41a4183bbf285058ef34a64.png)

这个Makefile就可以实现把打包库文件,然后使用make Output 就可以把头文件以及库文件一起打包放到一个文件,然后就只用打包交给用户就行了。
在这里插入图片描述

如何使用静态库

假设我们现在有一个刚才打包好的库,然后我们要使用它,应该怎么用?
这是库提供的头文件的内容。
在这里插入图片描述

这是源代码:

#include <stdio.h>
#include "mymath.h"                                                                                                                                                           
int main(){printf("3 + 2 = %d\n",add(3,2));printf("3 - 2 = %d\n",sub(3,2));return 0;
}

如果直接编译,肯定会报错
在这里插入图片描述
会提示找不到库提供的头文件,因为C语言在编译的时候,只会在系统特定的目录下和当前目录下查找头文件,库的头文件既不在当前目录下也不在系统的特定目录下当然找不到了,所以我们可以直接把头文件拷贝到系统目录下/user/include。
但是也可以使用gcc的-i选项指定搜索头文件的目录:
在这里插入图片描述
这时提示找不到库里面的方法,因为我们的是第三方库,需要告诉编译器我们要链接那个库,就需要gcc的-l选项:
在这里插入图片描述
这是有提示找不到库,因为编译器只会在默认路径(/usr/lib64)下搜索库,我们需要使用-L选项指定搜索库的路径。
在这里插入图片描述
这是就编译成功了,这就是使用静态库的大概流程,如果觉得太麻烦的话,最简单的办法就是把头文件和库都拷贝到系统的默认路径中。

动态库

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

动态库的制作

动态库依然是把.o文件打包,然后把.h和打包好的动态库一起交给用户,只不过动态库在形成.o是需要fPIC与位置无关码,打包.o文件直接使用gcc -shared 即可。
在这里插入图片描述

在这里插入图片描述

动态库的使用

动态库的使用和静态库一样,使用gcc命令,找不到头文件就用-i选项,-l指定需要链接的库,-L指定库的路径。
在这里插入图片描述
但是在运行的时候会有一些问题
在这里插入图片描述
我们可以使用ldd命令来查看一个可执行程序链接的动态库:
在这里插入图片描述
会发现找不到我们指定的库,这是因为我们虽然指定了库的路径,但是是给编译器指定的,程序编译成功成为可执行程序之后就和编译器没关系了,静态库没有这个问题是因为静态库是直接把自己需要的代码给自己拷贝了一份,而动态库是需要在运行的时候去动态库中找使用的函数,所以使用动态库链接的程序在运行的时候和库是强关联的。解决这个问题有很多种方法:

  1. 就是把头文件和库直接拷贝到系统的默认搜索路径中,即安装到系统。
  2. 使用软连接,可以在当前路径下或者库中建立软链接,因为动态库默认是会在当前路径下搜索的。
  3. 系统中有和环境变量LD_LIBRARY_PATH,可以把链接的动态库的路径添加到这个环境变量中,系统在搜索时会同时搜索这个环境变量中的路径。
  4. 直接更改系统的配置文件(etc/ld.so.conf.d/)
    在这里插入图片描述

gcc默认是动态连接的,但是个别库,如果只提供静态库(.a),gcc也没有办法,只能局部性的把指定的静态库进行静态连接,其他库正常进行动态链接,如果使用-static,对于该可执行程序,所有的库就都必须静态链接,对于同一组库,如果动态库和静态库都提供,gcc默认使用动态库。

动态链接

一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

使用了动态库的程序,在加载的时候,除了自己的代码数据需要的数组需要加载之外,使用到的动态库也是需要加载的,一般在虚拟地址空间中用映射的位置是,堆区和栈区之间的共享区。

程序被编译好之后,还没有被加载时它的内部其实就已经充满了各种各样的地址(函数,变量等),所谓的函数名变量名什么的在程序被编译好之后就都变成了地址,程序在编译的时候,对代码等进行编制,其实也是遵守我们虚拟地址空间的那一套的,所以虚拟地址空间不仅仅是OS的概念,更是一种标准。编译器在进行编译的时候,也要按照这样的规则编译可执行程序,这样才能在加载的时候,进行磁盘文件到内存后和进程空间进行映射。这种可执行程序为ELF格式的可执行程序。

因此程序内部的各种地址也是虚拟地址,程序在跳转到时候,需要执行到哪个虚拟地址的代码,根据页表直接找到对应的程序然后执行就可以了,因此CPU的每一次执行基本上都需要查表,这种虚拟地址也可以用基地址+偏移量的方式来表示,一般基地址是0,偏移量的范围[0,FFFFFFFF],这种地址成为逻辑地址,虚拟地址空间的这种模式为平坦模式。

我们知道位置有绝对位置和相对位置,同理编址的方式也有绝对编址和相对编址,而在我们代码中用到的库中的函数一般用的都是相对编制即相对于库的起始地址自己的位置,因为库在被加载的时候映射的位置不是固定的,每次映射的位置都是不一的,只用使用这样 库的名字 + 偏移量 的这种方式,才能保证库在加载是可以在共享区的任意位置进行加载。所以当库别加载之后地址就是确定的,然后用库的起始地址带起库的名字就可以很好的找到库中的任意函数。

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

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

相关文章

C++|对象与const

目录 常对象 常对象的声明 性质 数据成员不能被修改 常对象不能调用非const成员函数 const型成员函数 常对象成员 常数据成员 常成员函数 注意 总结 const型数据成员 const型成员函数 常对象 指针与const 指向对象的常指针 应用场景 指向常对象的指针 指向常…

Swagger3.0(Springdoc)日常使用记录

文章目录 前言一、默认地址二、注解OperationTag 三、SpringBoot基础配置四、Swagger导入apifox五、Swagger其他配置六 knife4j 参考文章 前言 本文并不是Swagger的使用教程&#xff0c;只是记录一下本人的操作&#xff0c;感兴趣的可以看下 一、默认地址 http://localhost:…

【1731】jsp 房租跟踪监控管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 房租跟踪监控管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

Java 基础常见面试题整理

目录 1、java的基本数据类型有哪些&#xff1f;2、java为什么要有包装类型&#xff1f;3、String a "123" 和 String a new String("123") 区别&#xff1f;4、String、StringBuilder和StringBuffer的区别&#xff1f;5、如何理解面向对象和面向过程&…

浅谈叉车车载电脑的市场现状

叉车的起源 叉车源于美国&#xff0c;兴于日本&#xff0c;虽然中国起步较晚&#xff0c;但是近些年来发展迅速。叉车又称叉式装载车&#xff0c;是对于成件托盘类货物进行装卸、堆垛和短距离运输&#xff0c;实现重物搬运作业的轮式工业车辆。 叉车的分类 叉车分为以上六大类…

CSS学习(选择器、盒子模型)

1、CSS了解 CSS&#xff1a;层叠样式表&#xff0c;一种标记语言&#xff0c;用于给HTML结构设置样式。 样式&#xff1a;文字大小、背景颜色等 p标签内不能嵌套标题标签。 px是相对于分辨率而言的&#xff0c; em是相对于浏览器的默认字体&#xff0c; rem是相对于HTML根元…

刷题日记 ---- 顺序表与链表相关经典算法题(C语言版)

目录 1. 移除元素2. 合并两个有序数组3. 移除链表元素4. 反转链表5. 合并两个有序链表6. 链表的中间结点7. 环形链表的约瑟夫问题8. 分割链表总结 正文开始 1. 移除元素 题目链接: 移除元素 题目描述: 思路历程: 题目明确要求, 不能使用额外的数组空间, 也就是说不可以创建…

【优质书籍推荐】AIGC时代的PyTorch 深度学习与企业级项目实战

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

springcloud按版本发布微服务达到不停机更新的效果

本文基于以下环境完成 spring-boot 2.3.2.RELEASEspring-cloud Hoxton.SR9spring-cloud-alibaba 2.2.6.RELEASEspring-cloud-starter-gateway 2.2.6.RELEASEspring-cloud-starter-loadbalancer 2.2.6.RELEASEnacos 2.0.3 一、思路 实现思路&#xff1a; 前端项目在请求后端接…

C++ 哈希

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;C知识分享⏪   &#x1f69a;代码仓库:C高阶&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C知识   &#x1f51d;&#x1f51d; ​ 前言 1. unordered系列关联式容器 1.1 unor…

必应bing国内广告开户注册教程!

今天搜索引擎广告成为企业推广产品与服务、提升品牌知名度的重要渠道之一。作为全球第二大搜索引擎&#xff0c;必应Bing凭借其高质量的用户群体和广泛的国际覆盖&#xff0c;为广告主提供了独特的市场机遇。在中国&#xff0c;虽然必应的市场份额相对较小&#xff0c;但对于寻…

磁密固定下的三次谐波与电压谐波的关系

同相位或者相位差为180的情况下&#xff0c;磁通密度三次谐波含量占比 α \alpha α&#xff0c;则电压三次谐波含量占比为 3 α 3\alpha 3α 同相位&#xff0c;磁通密度三次谐波含量占比 α \alpha α情况下&#xff0c; B B 0 sin ⁡ ( ω t ) α B 0 sin ⁡ ( 3 ω t )…

航空企业数字化解决方案(207页PPT)

一、资料描述 航空企业数字化解决方案是一项针对航空公司在数字化转型过程中所面临挑战的全面应对策略&#xff0c;旨在通过先进的信息技术提升航空企业的运营效率、客户服务水平以及市场竞争力。这份207页的PPT详细介绍了航空企业数字化的各个方面&#xff0c;包括关键技术的…

Web3技术解析:区块链在去中心化应用中的角色

引言 在过去几年中&#xff0c;Web3技术已经成为了互联网领域的一个热门话题。作为区块链技术的延伸&#xff0c;Web3不仅仅是数字货币的代名词&#xff0c;更是一个能够为各种应用提供去中心化解决方案的强大工具。本文将深入探讨区块链在Web3去中心化应用中的关键角色&#…

ubuntu查看opencveigen

ubuntu查看opencv&eigen&cmake版本的方法 eigen eigen版本号在/usr/include/eigen3/Eigen/src/Core/util/Macros.h文件中&#xff0c;下图代表版本3.3.7 opencv版本 pkg-config --modversion opencv4也可能最后的字符串是opencv2&#xff0c;opencv

W801学习笔记十二:掌机进阶V3版本之驱动(PSRAM/SD卡)

本次升级添加了两个模块&#xff0c;现在要把他们驱动起来。 一&#xff1a;PSRAM 使用SDK自带的驱动&#xff0c;我们只需要写一个初始化函数&#xff0c;并在其中添加一些自检代码。 void psram_heap_init(){wm_psram_config(0);//实际使用的psram管脚选择0或者1&#xff…

Java学习路线及自我规划

荒废了一段时间&#xff0c;这段时间的总结开始了JavaWeb的学习但是困难重重&#xff0c;例如Maven&#xff0c;Vue的路由等&#xff0c;所以我反省了一段时间&#xff0c;因为基础薄弱&#xff0c;加之学习的资源是速成视频&#xff0c;导致大厦将倾的局面&#xff08;也算不上…

RabbitMQ工作模式(5) - 主题模式

概念 主题模式&#xff08;Topic Exchange&#xff09;是 RabbitMQ 中一种灵活且强大的消息传递模式&#xff0c;它允许生产者根据消息的特定属性将消息发送到一个交换机&#xff0c;并且消费者可以根据自己的需求来接收感兴趣的消息。主题交换机根据消息的路由键和绑定队列的路…

盲人地图使用的革新体验:助力视障人士独立、安全出行

在我们日常生活中&#xff0c;地图导航已经成为不可或缺的出行工具。而对于盲人群体来说&#xff0c;盲人地图使用这一课题的重要性不言而喻&#xff0c;它不仅关乎他们的出行便利性&#xff0c;更是他们追求生活独立与品质的重要一环。 近年来&#xff0c;一款名为蝙蝠…

echarts地图叠加百度地图底板实现数据可视化

这里写自定义目录标题 echarts地图叠加百度地图实现数据可视化echarts地图叠加百度地图实现数据可视化 实现数据可视化时,个别情况下需要在地图上实现数据的可视化,echarts加载geojson数据可以实现以地图形式展示数据,例如分层设色或者鼠标hover展示指标值,但如果要将echa…