动静态库-动态库加载

动静态库

  • 前言
    • 引入
  • 一、静态库
    • 1. 创建静态库
      • ①原理
      • ②创建
    • 2. 使用静态库
      • ①借助编译选项
      • ②只需要带库名
    • 3. 小结
  • 二、动态库
    • 1. 创建动态库
    • 2. 使用动态库
  • 三、 动态库加载原理——进程地址空间
    • 1. 地址
      • ①程序没有被加载前的地址
      • ②程序加载后的地址
    • 2. 原理
      • ①动态库的地址
      • ②原理

前言

讲编译工具gcc时,讲到链接库,其中说静态链接和动态链接的相关知识,并且介绍了一些拓展命令,eg:od/file/ldd/readelf

接下来,目标:深入理解动静态库

引入

当我们想把我们写的代码给别人使用有两种方式:

  1. 直接把我们写的源文件和头文件给别人。
  2. 把源代码打包成库,加上头文件给别人。(库+.h)

优劣:

  • 第一种:相当于把底层的东西直接暴露给使用者。
  • 第二种:相当于只把使用说明(头文件)展示给使用者,使用者只知道如何调用方法,而不知道底层具体如何实现。

一、静态库

1. 创建静态库

①原理

生成库

  1. 静态库其实就是一堆.o文件打包形成
  2. 要先把源文件提前编译成目标文件
  3. 所以生成的库,人是读不出来的。

②创建

创建静态库

2. 使用静态库

开发者的库(xxx.a) + 使用者编写的代码(xxx.c) = 可执行程序(xxx.exe)

①借助编译选项

测试代码:
测试代码

  1. 直接编译一下试试:
    运行结果
    结果:运行失败
    结论:我们这里测试的头文件,不在系统指定的目录下(usr/include),所以gcc找不到这个头文件.
  1. 告诉编译器,头文件的位置。使用-I选项,后面跟头文件所在路径即可
    命令:gcc main.c -I ./lib/include
    运行结果
    结果:运行失败
    结论:这里不再是找不到头文件了,使用我们指定头文件路径这个是正确的,但是结果中的报错,是变量未定义报错,那很明显是链接报错,找不到静态库
  1. 告诉编译器,库的位置。使用-L选项,后面跟库文件所在路径即可
    命令:gcc main.c -I ./lib/include -L ./lib/mymathlib 运行结果
    结果:运行失败
    结论:指定库文件路径依旧不行,因为还要指定库文件名。为什么头文件就可以不指定文件名,那是因为在main.c中已经包含了头文件名
  1. 告诉编译器库的名称。使用-l选项,后紧跟库名。注:库名称是去掉lib和.a后缀。libmymath.a:mymath就是库名
    命令:gcc main.c -I ./lib/include -L ./lib/mymathlib -lmymath
    运行结果
    运行结果:
    运行结果

②只需要带库名

方法:

  1. 把头文件和库放到系统指定路径下,就可以只带-l编译选项。其实这个动作就是库的安装
  2. 头文件和库在系统指定的目录下,建立软链接,就可以只带-l编译选项(这个下面演示一下)

演示:给头文件和库在系统指定目录下建立软链接

  1. 对头文件建立软链接 对头文件建立软链接
    • 查看系统指定目录下的软链接:建立软链接成功 软链接
    • 因为是在/usr/include目录下建立了一个路径的软链接,所以在测试使用的要包含头文件的方式要改变
      头文件包含
  • 运行程序
    命令:gcc main.c -L ./lib/mymathlib -lmymath 注意:因为头文件的软链接被放到系统的指定目录下,所以就不需要使用-I选项
    运行结果:
    运行结果
  1. 对静态库建立软链接 对静态库建立软链接
  • 运行程序
    命令:gcc main.c -I ./lib/include -lmymath 注:因为库的软链接被放到系统的指定目录下,所以就不需要使用-L选项
    运行结果:
    运行结果

注:把头文件和库在系统指定的目录下,一起建立软链接,就可以只适用-l选项。上面的演示,我没有放在一起,所以要么带L选项,要么就要带I选项

3. 小结

使用总结:

  1. 大写i(I)指定头文件所在路径
  2. 大写l(L)指定库所在路径
  3. 小写l(l)指定库名称。注:库名称是去掉lib和.a后缀

静态库总结:

  1. 把头文件和库都移动到系统的指定目录下就可以不加选项I和L,但是只要使用第三方库必定要使用gcc -l[库名](第一二方,可以理解为系统和语言层次的库)
  2. 在系统指定目录下建立软链接也可以不加选项I和L
  3. 理解库中的全局变量
  4. 如果系统只提供静态库,则编译器就只能进行静态链接
  5. 可以链接多个库

二、动态库

1. 创建动态库

创建动态库的两个关键命令

  1. 生成目标文件:gcc -fPIC -c $^
  2. 生成动态库:gcc -shared -o $@ $^

生成动态库,并且分类:
创建动态库

注:发现生成的动态库具有可执行权限 生成的动态库
虽然具有可执行权限,但是并不能执行
可执行权限:以可执行程序的方式加载到内存

2. 使用动态库

测试代码:
测试代码

  1. 编译:根据对静态库使用的编译选项,指定路径测试动态库
    命令:gcc test.c -I ./mylib/include -L ./mylib/lib -lmymethod
    编译
    结果:编译成功,生成了可执行程序a.out
  2. 运行:
    运行结果
    结果:运行失败,没有发现共享库

注:ldd命令:显示可执行程序链接的动态库

  1. 原因:
    • 因为是动态库要加载到内存。编译器确实知道了动态库的位置,但是我系统不知道——加载器
  2. 解决:
    • 拷贝到系统默认的库路径/lib64 or /usr/lib64(最常用,我们以后使用的库,都是别人成熟的库,所以可以直接安装都系统指定的目录下)
    • 在系统默认的库路径(/lib64 or /usr/lib64)下建立软链接
    • 将自己的库所在的路径,条件到系统的环境变量LD_LIBRARY_PATH中
    • /etc/ld.so.conf.d建立自己的动态库路径的配置文件,然后加载(ldconfig)

这里测试一下后面两种解决办法,前面俩种拷贝和建立软链接就不测试了

  1. 环境变量:
    解决
    • 注:重启Xshell之后,环境变量就恢复了,所以如果想一直可以,就要在配置文件中进行添加
  2. 建立自己的动态库路径的配置文件
    解决
    • 注:
      1. 添加配置文件操作需要在root账号下
      2. 进入/etc/ld.so.conf.d目录下
      3. 创建一个以.conf为后缀的文件,名字任意
      4. 文件内填入需要使用的动态库路径
      5. ldconfig更新

如果还要添加别的路径下的动态库,需要再创建文件然后写入路径

注:外部库很多,eg:ncurses库——基于终端的图形界面库(可以上网搜下载一下玩玩)

三、 动态库加载原理——进程地址空间

  1. 动态库在进程运行的时候,是要被加载的
  2. 常见的动态库被所有的可执行程序使用(eg:c标准库就被Linux很多指令共享使用)。动态库 —— 共享库

所以动态库在系统加载后,会被所以进程共享

1. 地址

①程序没有被加载前的地址

问题:程序在编译好之后,没有运行前,内部有地址吗?

通过命令,可以把编译好的程序反汇编出来
命令:objdump -S a.out
在这里插入图片描述

所以程序编译好之后,内部就有地址了,而且现在的编译器大多会采用平坦模式。这个地址就是虚拟地址,更准确的说是逻辑地址,对于目前来说,二者并没有什么区别,所以还没加载到内存,这个虚拟地址已经出现了
注:
平坦模式:内存管理模式,它将整个内存地址空间视为一个连续的线性地址空间,从0递增,程序可以直接使用线性地址进行访问

②程序加载后的地址

把可执行程序加载到内存,必然要先形成好自己的PCB
图解:
图解

2. 原理

①动态库的地址

图解:
图解

所以也得出为什么采用fPIC(产生位置无关码),因为直接用偏移量对库中的函数进行编址。而静态库就不需要这样做,因为静态库是直接拷贝到可执行程序中去的,直接编址就可以

②原理

图解:
图解

  1. 结论:虚拟地址和物理地址建立映射,从此执行任何的代码,都是在我们的进程地址空间中执行的
  2. 事实:系统在运行的时候,一定存在很多个动态库。所以OS就得管理起来 —— 先描述再组织。所以系统中所有库的加载情况,OS都清楚

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

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

相关文章

【AI视野·今日CV 计算机视觉论文速览 第301期】Mon, 4 Mar 2024

AI视野今日CS.CV 计算机视觉论文速览 Mon, 4 Mar 2024 Totally 74 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Point Could Mamba: Point Cloud Learning via State Space Model Authors Tao Zhang, Xiangtai Li, Haobo Yuan, Shunping …

Python从0到100(二):Python语言介绍及第一个Pyhon程序

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

VELO Angel Glide骑行如风,为你的骑行生活添上一抹亮色~

骑行美学,不就是骑得飞快,姿势还帅吗?但别忘了头盔和护膝,还有多数人忽视的骑行坐垫——毕竟安全骑行才是真的美哦。    我曾经一直苦恼于骑行过程中坐垫为你带来的不适感,也曾萌生退意,直到我遇见了这…

基于springboot+vue的图书管理系统

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

JavaScript的`bind`方法:函数的“复制”与“定制”

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

SPC 之 I-MR 控制图

概述 1924 年,美国的休哈特博士应用统计数学理论将 3Sigma 原理运用于生产过程中,并发表了 著名的“控制图法”,对产品特性和过程变量进行控制,开启了统计过程控制新时代。 什么是控制图 控制图指示过程何时不受控制&#xff…

java spring 03 启动细节

spring启动类ClassPathXmlApplicationContext,读取xml文件并且创建bean public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(confi…

数据分析-Pandas数据y轴双坐标设置

数据分析-Pandas数据y轴双坐标设置 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表&…

【笔记】Android 漫游定制SPN定制有关字段

一、SPN模块简介 【笔记】SPN和PLMN 运营商网络名称显示 Android U 配置 WiFiCalling 场景下PLMN/SPN 显示的代码逻辑介绍 【笔记】Android Telephony 漫游SPN显示定制(Roaming Alpha Tag) 二、相关配置字段 non_roaming_operator_string_array 是否…

RHCSA练习2

一、实验题目 1、文件查找 (1)在当前目录及子目录中,查找小写字母开头的txt文件 [rootroot ~]# cd /etc [rootroot etc]# find . -type f -name [a-z]*.txt (2)在/etc及其子目录中,查找host开头的文件 …

2024年最新appstore公司账号申请

首先申请一个邮箱、然后打开Sign In - Apple 进行邮箱appID 注册、等appID注册成功以后、会下一步提示你进行账号申请:此时 有个需要注意的问题是:这块的信息必须填写真实的姓名、后续上传资料的时候会与这块进行匹配,不一致会导致很多问题。 就会出现上述图,让你去下载这…

针对有容量的电动汽车路由问题的灵活交叉的修正遗传算法

英文:Modified Genetic Algorithm with Flexible Crossover for The Capacitated Electric Vehicle Routing Problem 摘要 本文提出了一种对遗传算法的修改,用一种叫做灵活交叉操作的新技术来解决有容量的电动汽车路由问题(CEVRP&#xff0…