Linux复习 / 动静态库QA梳理 | 如何使用第三方库?

news2024/10/7 6:39:39

文章目录

    • 前言
    • Q&A
      • 概念
        • Q:使用静态库和使用动态库的程序有什么区别?
        • Q:什么是静态链接/动态链接?
      • 使用与制作
        • Q:如何制作动静态库?
        • Q:如何使用第三方库?
        • Q:程序加载时,链接器查找动态库文件的顺序?
      • 原理
        • Q:怎么从进程地址空间的角度理解动态库?

前言

本篇博客梳理关于动静态库相关的Q&A,这是Linux复习中的一部分。若读者也在复习这块知识,或者正在学习这块知识,可以通过这些Q&A检测自己的知识掌握情况。此外,思维导图已经更新至我的gitee,Q&A之外的体系梳理还请移步思维导图。

Q&A


概念

Q:使用静态库和使用动态库的程序有什么区别?

A:

  • 静态库(.a):程序编译时会将静态库的二进制代码拷贝到程序代码中,运行时不再需要链接外部静态库
  • 动态库(.so):程序编译完成,运行时才会去链接外部的动态库,不需要将动态库拷贝到程序的代码中

Q:什么是静态链接/动态链接?

A:

  • 静态链接:首先要明白的是:main函数所在的obj文件可以和其他obj文件一起编译,生成可执行文件。而静态库中有多个obj文件,将这些obj文件与main函数所在的obj文件一起编译,这个过程就叫做静态链接。静态链接需要编译除自己之外的其他obj文件,生成的可执行文件会占用更多的空间
  • 动态链接:使用动态库的可执行文件含有一张动态符号表,表中包含了需要用到的函数符号。动态库也有一张动态符号表,包含了动态库的函数符号。程序运行时,系统将动态库从磁盘加载到内存。同时,动态链接器根据符号表将程序与动态库之间建立绑定。一个动态库可以绑定多个程序的动态符号表,也就是可以被多个程序使用。使用动态库的程序,编译生成的可执行文件将占用更少的空间

关于动态链接器的链接过程:符号解析 + 重定位

  1. 动态链接器根据程序中的符号引用和动态库中的符号定义生成一张符号表,用来记录程序中每个符号在内存中的地址
  2. 动态链接器遍历程序的重定位条目,根据符号表中的地址信息,修改程序中符号的引用,使它们指向正确的内存位置
  3. 动态链接器调用动态库的初始化函数,完成必要的初始化工作
  4. 动态链接器将控制权交给程序的入口点,使程序开始执行

使用与制作

Q:如何制作动静态库?

A:

  1. 动态库的制作:必须使用位置无关的obj文件
  • 编译obj文件时:gcc -fPIC -c (源文件名) -o (生成的obj文件名)
  • 生成动态库时:gcc -shared (源obj文件…) -o (生成的动态库名)
  1. 静态库的制作:使用位置有关的obj文件
  • 使用ar -rc (要生成的静态库名称) (要归档的obj文件)指令归档一个静态库
  1. 最后创建一个总目录,其中有两个子目录,一个放头文件,一个放obj文件

image.png

Q:如何使用第三方库?

A:首先,无论是动态库还是静态库,源程序都需要包含头文件(函数的声明)。这样做可以使得程序编译成功,但是无法进行链接

  • 静态库:编译器在链接时,会在/usr/lib64这个默认路径下搜索源程序需要链接的库,在/usr/include这个路径下搜索需要使用的头文件。通常我们会用到标准库,所以编译器会默认在/usr/include和/usr/lib64这两个路径下查找头文件与标准库并且链接标准库。若源程序需要使用第三方库,就需要告知编译器:头文件所在路径、需要链接的库及其所在路径
    • 若第三方库和第三方头文件已经添加到/usr/lib64和/usr/include目录下,那么编译源文件时,只要带上-l 选项,告知编译器要链接的库。比如
gcc test.c -l myfirst -o test
  • 要注意的是:一般库文件名称都含有"lib"的前导和".so"或".a" 的后缀。比如libmyfirst.so和libmyfirst.a,使用-l选项时,需要去除"lib"前导与".*"的后缀。比如libmyfirst.so写为myfirst
  • 若第三方库和第三方头文件没有添加到默认路径下,那么就需要使用-I (头文件所在路径)和-L (库文件所在路径)告知编译器库文件与头文件所在的位置。比如
gcc test.c -L ../lib-static/lib -I ../lib-static/include -l myfirst
               库文件所在路径        头文件所在路径      要链接的库      
  • 动态库:同样,使用动态库有两种方法,一种是简单的向默认路径添加库文件与头文件,编译时只使用-l选项。另一种使用-L、-I、-l三个选项进行编译。注意:对于后者,源程序依然可以编译成功,但是程序无法执行,一旦执行就会崩溃,原因是:
    • 虽然编译器知道源程序依赖的库文件所在路径,编译器根据库文件生成符号表。但是程序加载时,操作系统需要进行动态链接 ,这个过程需要加载动态库到内存并修改符号表,使其指向正确的内存位置。然而进行动态链接的动态链接器不知道动态库所在的位置(磁盘中的位置),动态链接的过程无法进行。解决方法是:
    • 采用第一种方法,将动态库文件添加到默认路径下
    • 向环境变量LD_LIBRARY_PATH导入动态库路径(用export设置)。动态链接时,链接器除了会在默认路径下查找库文件,还会解析LD_LIBRARY_PATH中的路径,查找变量中的路径。不过系统一旦重新,环境变量重置,需要重新配置才能使程序正确运行
    • 修改系统配置文件。/etc/ld.conf.so.d/目录下存储了系统的配置文件,每个配置文件存储了一个路径,将库文件所在的绝对路径为内容创建我们的配置文件,并添加到该路径下。添加完成使用sudo ldconfig指令,加载配置文件即可
    • 与第一种方式类似,向默认路径下以绝对路径的方式添加软连接。使用指令
sudo ln -s /home/xx/xxx/lib-dynamic/libmyfirst.so /usr/lib64/libmyfirst.so
                    库文件的绝对路径              需要在系统中创建的软链接文件

Q:程序加载时,链接器查找动态库文件的顺序?

A:动态链接器会根据以下顺序查找动态库文件,若都无法找到,动态加载失败,程序将崩溃

  1. 在环境变量LD_LIBRARY_PATH中存储的指定路径中查找,使用export设置
  2. 在/etc/ld.conf.so.d/目录下根据配置文件存储的路径查找,使用ldconfig使配置生效
  3. 默认的/usr/lib64路径
    其实一开始,动态链接器会根据程序硬编码的RPATH或RUNPATH选项指定的路径查找。不过我们一般都不会设置这两个选项,因为这会降低程序的可移植性和灵活性,所以我没有在上面提及。

原理

Q:怎么从进程地址空间的角度理解动态库?

A:加载程序时,系统就要为其分配进程地址空间,堆区往上栈区往下之间有一个区域:共享区,共享区有很多作用,其中一个是:存储动态库函数的映射地址。映射地址只是虚拟地址,由于动态库函数的地址是在程序运行时才确定的,而共享区在程序加载时就需要进行创建。所以操作系统会在动态库函数地址确定之后修改页表,使共享区的映射地址指向正确的动态库函数地址。

运行使用动态库的程序的主要过程:

  1. 系统将程序对应的可执行文件和需要使用的动态库加载到内存中
  2. 系统创建为可执行文件创建进程,建立进程地址空间,页表。同时调用动态链接器,进行符号解析和重定位
  3. 当系统为动态库函数分配好了空间,系统将修改进程的页表,使共享区的动态库函数映射地址指向正确的地址
  4. 当进程调用动态库函数时,会跳转到共享区,获取函数的映射地址,经过页表的转换找到函数并且执行。函数执行完,程序会从共享区跳转回原来的区域,继续往下执行代码

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

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

相关文章

C语言-实现顺序二叉树和平衡二叉树AVL

1. 结构体 在实现二叉树之前先看下结构体的一些使用方法 数组是保存一系列相同的数据。在实际问题中,一组数据往往有很多种不同的数据类型。例如,登记学生的信息,可能需要用到 char型的姓名,int型或 char型的学号,in…

4.6--计算机网络之TCP篇之TCP的基本认识--(复习+深入)---好好沉淀,加油呀

1.TCP 头格式有哪些? 序列号: 在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。 用来解决网络包乱序问题。 确认应答号: …

MySQL优化——Explain分析执行计划详解

文章目录前言一. 查看SQL执行频率二. 定位低效率执行SQL三. explain分析执行计划3.1 id3.2 select_type3.3 table3.4 type3.5 key3.6 rows3.7 extra四. show profile分析SQL前言 在应用的的开发过程中,由于初期数据量小,开发人员写 SQL 语句时更重视功能…

酷炫的3D智慧工厂不会打造?这40+可视化大屏模板千万别错过!

数字化已成为各行各业的重要趋势,因为数字化能够带来精准的效益提升。小米公司最近推进了黑灯工厂业务。”24小时熄灯操作,全程无人工干预”,这是小米智能工厂的重要特征。走进工厂,闪烁的灯带提示生产正在进行,机器通…

【Spring从成神到升仙系列 四】从源码分析 Spring 事务的来龙去脉

👏作者简介:大家好,我是爱敲代码的小黄,独角兽企业的Java开发工程师,CSDN博客专家,阿里云专家博主📕系列专栏:Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到升仙…

【ChatGPT】Prompt Engineering入门

Prompt Engineering入门一、什么是 Prompt Engineering?二、我们还需要学习 PE 吗?三、Prompt基础原则一、什么是 Prompt Engineering? 简单的理解它是给 AI 模型的指令。它可以是一个问题、一段文字描述,甚至可以是带有一堆参数的…

数据结构 - 排序 | C (插入、希尔、选择、堆、冒泡)

目录0.排序思维导图(总)一、插入排序1.直接插入排序思路分析代码实现时间复杂度2.希尔排序思路分析代码实现时间复杂度二、选择排序1.选择排序思路分析代码实现时间复杂度2.堆排序思路分析代码实现时间复杂度三、交换排序冒泡排序思路分析代码实现时间复…

如何基于vue实现倒计时效果

如何基于vue实现倒计时效果基于vue2 element实现画面效果代码基于vue2 element 实现画面效果 代码 <template><div><div class"Box"><div style"position: relative;"><el-progress type"circle" :width"30…

pytorch注意力机制

pytorch注意力机制 最近看了一篇大佬的注意力机制的文章然后自己花了一上午的时间把按照大佬的图把大佬提到的注意力机制都复现了一遍&#xff0c;大佬有一些写的复杂的网络我按照自己的理解写了几个简单的版本接下来就放出我写的代码。顺便从大佬手里盗走一些图片&#xff0c…

Vue3使用触摸滑动插件(Swiper)

Vue2使用触摸滑动插件&#xff08;Swiper&#xff09; 参考文档&#xff1a; Swiper官方 Swiper Vue Swiper Demos 本文使用的是最新版本&#xff1a;Swiper9.2.2 安装插件&#xff1a;yarn add swiper 本文基于Swiper插件进行封装&#xff0c;主要实现两种形式的轮播图展示…

电脑自带远程桌面和远程控制软件哪个好?

随着科技的不断发展和普及&#xff0c;越来越多的公司和个人开始关注远程控制软件的使用。我们常常需要在不同的地方工作&#xff0c;但工作需要的文件和软件却只能在一个地方使用&#xff0c;这时候远程控制电脑软件就变得尤为重要咯。但是&#xff0c;许多人分不清楚&#xf…

Windows远程连接工具有哪些

Windows远程连接工具&#xff0c;一般称为远程桌面软件&#xff0c;更准确的叫远程访问软件或远程控制软件&#xff0c;可以让你从一台电脑远程控制另一台电脑。远程桌面软件允许您控制连接的计算机&#xff0c;就好像它就在您面前一样。 远程桌面工具可用于技术支持、远程工作…

单TYPE-C口 可支持快充又可传输USB2.0数据方案

虽然现在有不少厂商也采用了Type-C接口&#xff0c;但是只作为一个充电接口&#xff0c;对于跨时代的type-c接口来说&#xff0c;多少有点大材小用&#xff0c; 那么有没有办法&#xff0c;让一个type-c接口既可以充电&#xff0c;又可以接OTG&#xff1f;比如不充电的时候可以…

Python一行命令搭建HTTP服务器并外网访问 - 内网穿透

文章目录1.前言2.本地http服务器搭建2.1.Python的安装和设置2.2.Python服务器设置和测试3.cpolar的安装和注册3.1 Cpolar云端设置3.2 Cpolar本地设置4.公网访问测试5.结语转载自远程内网穿透的文章&#xff1a;【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透」 1…

第二章:HTML CSS 网页开发基础(二)

CSS概述 CSS全称&#xff1a;Cascading Style Sheet&#xff0c;可以对文字进行重叠&#xff0c;定位。主要实现页面美化。 一、CSS规则 CSS样式表中包括了3部分&#xff1a;选择符、属性、属性值 选择符{属性:属性值;} 选择符&#xff1a;也可以称为选择器&#xff0c;所有…

Java实现输入行数打印取缔字符,打印金字塔三角形的两个代码程序

目录 前言 一、实现输入行数&#xff0c;打印取缔字符 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图 二、打印金字塔三角形 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图​​​​​​​ 前言 1.因多重原因&#xff0c;本博文有…

【BlazePose】《BlazePose: On-device Real-time Body Pose tracking》

arXiv-2020 文章目录1 Background and Motivation2 Advantages / Contributions3 Method4 Experiments5 Conclusion&#xff08;own&#xff09;1 Background and Motivation 人体关键点存在的难点&#xff1a;a wide variety of poses, numerous degrees of freedom, and occ…

JavaWeb—Maven

目录 1.什么是Maven 2.Maven的作用 3.Maven概述 3.1Maven介绍 3.2 Maven模型 3.3 Maven仓库 1.什么是Maven Maven是Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 官网&#xff1a;Maven – Welcome to Apache Mavenhttps://maven.apache.o…

vscode 终端集成bash

windows 版本的 vs code 终端默认是没有集成bash的&#xff0c;虽然也能在vscode 终端可以提交git&#xff0c;但是没有高亮&#xff0c;没有提示&#xff0c;很不方便&#xff0c;这时候就需要我们将bash集成到vs code的终端&#xff0c;就可以愉快的使用git的分支高亮&#x…

阿里云蔡英华:云智一体,让产业全面迈向智能

4月11日&#xff0c;在2023阿里云峰会上&#xff0c;阿里云智能首席商业官蔡英华表示&#xff0c;算力的飞速发展使数字化成为确定&#xff0c;使智能化成为可能。阿里云将以云计算为基石&#xff0c;以AI为引擎&#xff0c;参与到从数字化迈向智能化的划时代变革中。 基于服务…