动静态库以及动态链接

news2025/1/16 11:03:50

文章目录

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

库是给别人用的,所以库中一定不存在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.coloradmin.cn/o/1628485.html

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

相关文章

OpenHarmony实战开发-使用SmartPerf-Host分析应用性能

简介 SmartPerf-Host是一款深入挖掘数据、细粒度展示数据的性能功耗调优工具&#xff0c;可采集CPU调度、频点、进程线程时间片、堆内存、帧率等数据&#xff0c;采集的数据通过泳道图清晰地呈现给开发者&#xff0c;同时通过GUI以可视化的方式进行分析。该工具当前为开发者提…

C#技巧之窗体去鼠标化

简介 在窗体程序中不用鼠标&#xff0c;直接使用键盘完成想要的操作。 实现的方法有两种&#xff0c;一种是使用键盘上的Tab键使控件获得焦点&#xff0c;然后用enter键触发该控件上的事件&#xff08;一般为click事件&#xff09;。另一种是&#xff0c;为控件添加快捷键&am…

优维全新力作:统一采控平台

在本月&#xff0c;优维新一代核心系统「EasyOps」7.0大版本重磅上线&#xff0c;为广大用户带来了“更核心、更智能、更开放、更客制”的产品能力。&#xff08;点击回看&#xff1a;重磅&#xff01;优维科技发布EasyOps7.0大版本&#xff09;在本次版本能力分享上&#xff0…

基于springboot实现中药实验管理系统设计项目【项目源码+论文说明】计算机毕业设计

基于springboot实现中药实验管理系统设计演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了中药实验管理系统的开发全过程。通过分析中药实验管理系统管理的不足&#xff0c;创建了一个计算机管理中药实验管…

基于WOA鲸鱼优化的购售电收益与风险评估算法matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于WOA鲸鱼优化的购售电收益与风险评估算法.WOA优化算法是一种基于鲸鱼捕食过程的仿生优化算法&#xff0c;其包括鲸鱼行走觅食、鲸鱼包围以及鲸鱼螺旋捕食三个步骤。在WOA优…

用 Python 创建 Voronoi 图

概述 最常见的空间问题之一是找到距离我们当前位置最近的兴趣点 (POI)。假设有人很快就会耗尽汽油&#xff0c;他/她需要在为时已晚之前找到最近的加油站&#xff0c;解决这个问题的最佳解决方案是什么&#xff1f;当然&#xff0c;驾驶员可以检查地图来找到最近的加油站&…

C++从入门到精通——string类

string类 前言一、为什么学习string类C语言中的字符串示例 二、标准库中的string类string类string类的常用接口说明string类对象的常见构造string类对象的容量操作string的接口测试及使用string类对象的访问及遍历操作下标和方括号遍历范围for遍历迭代器遍历相同的代码&#xf…

6.模板初阶

目录 1.泛型编程 2. 函数模板 2.1 函数模板概念 2.2函数模板格式 2.3 模板的实现 2.4函数模板的原理 2.5 函数模板的实例化 3.类模板 1.泛型编程 我们如何实现一个 交换函数呢&#xff1f; 使用函数重载虽然可以实现&#xff0c;但是有一下几个不好的地方&#xff1a; …

iOS - 多线程-读写安全

文章目录 iOS - 多线程-读写安全1. 多读单写1.1 场景1.2 实现方案1.2.1 pthread_rwlock&#xff1a;读写锁1.2.1.1 示例 1.2.2 dispatch_barrier_async&#xff1a;异步栅栏调用1.2.2.1 示例 iOS - 多线程-读写安全 假设有一个文件&#xff0c;A线程进行读取操作&#xff0c;B…

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

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

linux系统-FTP服务配置

目录 一、FTP简介 1.什么是FTP&#xff1f;&#xff1f;&#xff1f; 2.FTP的两种模式 二、安装配置FTP服务 1.关闭防火墙和核心防护 2.安装VSFTPD 3.修改配置文件 4.黑白名单设置 一、FTP简介 1.什么是FTP&#xff1f;&…

【Node.js工程师养成计划】之打造自己的脚手架工具

一、创建全局的自定义命令 1、打开一个空文件夹&#xff0c;新建一个bin文件夹&#xff0c;在bin文件夹下新建cli.js文件&#xff0c;js文件可以命名为cli.js&#xff08;您随意&#xff09; 2、在cli.js文件中的开头&#xff08;&#xff01;&#xff01;&#xff09;写下面这…

Prometheus Metrics指标类型 Gauge(仪表盘)

指标是用来衡量性能、消耗、效率和许多其他软件属性随时间的变化趋势。它们允许工程师通过警报和仪表盘来监控一系列测量值的演变&#xff08;如CPU或内存或磁盘使用量、请求持续时间、延迟等&#xff09;。指标在IT监控领域有着悠久的历史&#xff0c;并被工程师广泛使用&…

Linux下的UDEV机制/守护进程

一. Udev机制 二. 守护进程 1. 概念&#xff1a; 2. 基本特点&#xff1a; a. 生存周期长&#xff0c;一般操作系统启动的时候就启动&#xff0c;关闭的时候关闭&#xff08;这是由开发人员自行将守护进程添加到开机启动项的&#xff09;。 b. 守护进程和终端无关联&#…

云备份项目->配置环境

升级gcc到7.3版本 sudo yum install centos-release-scl-rh centos-release-scl sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c source /opt/rh/devtoolset-7/enable echo "source /opt/rh/devtoolset-7/enable" >> ~/.bashrc 安装Jsoncpp库 sud…

知识分享之cookie

http协议中的cookie&#xff0c;什么是cookie如何获取cookie 一、什么是Cookie Cookie&#xff08;曲奇&#xff0c;小甜饼的译名&#xff09;在互联网技术领域中&#xff0c;是指一种小型文本文件&#xff0c;它由网站服务器发送给用户的浏览器&#xff0c;并被浏览器存储在用…

【春 联---turtle海龟画图】

春联 又称"春贴"、"门对"、"对联"&#xff0c;是过年时所贴的红色喜庆元素"年红"中一个种类。它以对仗工整、简洁箱巧的文字描绘美好形象&#xff0c;抒发美好愿 望&#xff0c;是中国特有的文学形式&#xff0c;是华人们过年 的重要习…

windows/linux 安装php的 sql server 扩展

Windowsphpstudyphp7.1 下载&#xff1a;ODBC、下载php 的sql server 扩展 路径&#xff1a;下载地址 版本&#xff1a;我的是7.1 对应的ODBC 是13&#xff0c;php 的sql server 扩展为4.3 安装&#xff1a;msodbcsql 直接安装、sqlsrv43 安装完把 扩展复制到php71 的扩展文…

c#学习入门2

十、运算符 1&#xff09;算术运算符是用于数值类型变量计算的运算符&#xff0c;它返回的结果是数值 1.赋值符号 2.算数运算符 加 减- 乘* 除/ 取余% 3.算数运算符的优先级 4.算术运算符的复合运算 5.算术运算符的自增减 2&#xff09;字符串拼接 1.字符串拼接方式1 注意&…

antd 日期控件RangePicker如何增加快捷键(日/周/月/年)

注意&#xff1a;快捷键是从当前日期往前推算的 效果 代码 <script><RangePickerranges{{日: [moment(new Date().setDate(new Date().getDate() - 1)), moment(new Date())],周: [moment(new Date().setDate(new Date().getDate() - 7)), moment(new Date())],月: […