Linux笔记--静态库和动态库

        库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为"库"文件;在链接步骤中,链接器将从库文件取得所需的代码,复制到生成的可执行文件中。

Linux中常见的库文件有两种,一种.a为后缀,为静态库,另一种以.so为后缀,为动态库

一、静态库

        可重定位目标文件以一种特定的方式打包成一个单独的文件,并且在链接生成可执行文件时,从这个单独的文件中“拷贝"它自己需要的内容到最终的可执行文件中。这个单独的文件,称为静态库。Linux中这类库的名字一般是libxxx.a。

1.创建步骤

将add.c sub.c创建成静态库文件:

  • 创建add.c sub.c
#add.cint add (int a, int b) 
{return a + b;
}#sub.cint sub (int a, int b) 
{return a - b;
}
  • 对add.c sub.c编译成可重定位目标文件
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
  • 利用ar工具创建静态库: ar rcs lib 库名.a所有可重定位目标文件
#生成静态库
ar rcs libmath.a add.o sub.o 

2.静态库的使用

制作使用libmath.a静态库的程序

  • 创建main.c
#include<stdio.h>int add(int a,int b);
int sub(int a,int b);int main(int argc, char* argv[])
{int a=5,int b=3;printf("a+b=%d\n",add(a,b));printf("a-b=%d\n",sub(a,b));    return 0;
}
  • 编译main.c

编译时要将静态库libmath.a加上gcc选项:

  • l:指定库名(库的文件名为libxxx.a,库名为xxx)
  • L:指定库路径
  • static:使用静态链接
gcc -static main.c -l math -L ./
#注意:要先运行main.c后运行静态库文件./a.out

特别注意,必须把-l math 放在后面。放在最后时它是这样的一个解析过程:

  • 链接器从左往右扫描可重定位目标文件和静态库
  • 扫描main.c时,发现两个未解析的符号add和sub,记住这两个未解析的符号
  • 扫描libmath.a,找到了前面未解析的符号,因此提取相关代码
  • 最终没有任何未解析的符号,编译链接完成

那如果将-l math放在前面,又是怎样的情况呢?

  • 链接器从左往右扫描可重定位目标文件和静态库
  • 扫描libmath.a,由于前面没有任何未解析的符号,因此不会提取任何代码
  • 扫描main.c,发现未解析的符号add和sub
  • 扫描结束,还有两个个未解析的符号,因此编译链接报错

生成可执行文件大小:

        生成的可执行文件大小为826k

        由于最终生成的可执行文件中已经包含了add和sub相关的二进制代码,因此这个可执行文件在一个没有libmath.a的Linux系统中也能正常运行。

二、动态库

        动态库和静态库类似,但是它并不在链接时将需要的二进制代码都“拷贝"到可执行文件中,而是仅仅“拷贝”一些重定位和符号表信息,这些信息可以在程序运行时完成真正的链接过程。Linux中这类库的名字一般是libxxx.so。(shared object)

1.创建步骤

//先编译成可重定位目标文件(生成与位置无关的代码-fPIC)
gcc -c add.c -o add.o -fPIC
gcc -c sub.c -o sub.o -fPIC
//使用gcc -shared 制作动态库
gcc -shared -o libmath.so add.o sub.o

-fPC作用:生成与位置无关的代码

2.动态库的使用

        通常我们编译的程序默认就是使用动态链接

gcc main.c -o main -l math -L ./

        通过动态库链接的程序只有8.5k.

        通过 ldd命令来观察可执行文件链接了哪些动态库:

        因为没有把 libmath.so 中的二进制代码“拷贝"可执行文件中,程序在其他没有上面的动态库时,将无法正常运行。

3.找不到动态库

        运行可以执行程序./main出错!!! ldd main --> "not found"

        链接器:工作于链接阶段,工作时需要-l和L

        动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。

        原因:没有提供动态库的位置

解决方式:

  • 通过环境变量(临时生效): export LD_LIBRARY_PATH=动态库路径
  • 环境变量写入配置文件~/.bashrc(使用绝对路径),生效方法: .~/.bashrc或source ~/.bashrc 或 重启终端
  • 拷贝自定义动态库到lib(标准C库所在目录位置)(不推荐)

        【注】只是临时生效。关闭终端再重启时使用./main还会报错。如果想要一直生效需要写在配置文件中。

动态库绝对路径写到/etc/ld.so.conf配置文件中,生效方法: sudo ldconfig

三、静态库和动态库的区别

        静态库被使用目标代码最终和可执行文件在一起(它只会有自己用到的),而动态库与它相反,它的目标代码在运行加载时链接。正是由于这个区别,会导致下面所介绍的这些区别。

1.可执行文件大小

        静态链接的可执行文件要比动态链接的可执行文件要大得多,因为它将需要用到的代码从二进制文件中“拷贝”了一份,而动态库仅仅是复制了一些重定位和符号表信息。

2.扩展性与兼容性

        如果静态库中某个函数的实现变了,那么可执行文件必须重新编译,而对于动态链接生成的可执行文件,只需要更新动态库本身即可,不需要重新编译可执行文件。正因如此,使用动态库的程序方便升级和部署。

3.依赖原库文件

        静态链接的可执行文件不需要依赖其他的内容即可运行,而动态链接的可执行文件必须依赖动态库的存在。所以如果你在安装一些软件的时候,提示某个动态库不存在的时候也就不奇怪了。

即便如此,系统中一般存在一些大量公用的库,所以使用动态库并不会有什么问题。

4.加载速度

        由于静态库在链接时就和可执行文件在一块了,而动态库在加载或者运行时才链接,因此,对于同样的程序,静态链接的要比动态链接加载更快。所以选择静态库还是动态库是空间和时间的考量。但是通常来说,牺牲这点性能来换取程序在空间上的节省和部署的灵活性时值得的。

5.库的制作复杂度

        相对来讲,动态库的处理要比静态库要复杂,例如,如何在运行时确定地址?多个进程如何共享一个动态库?当然,这些我们不需要关注。另外动态库版本的管理也是一项技术活。

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

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

相关文章

GIS之深度学习10:运行Faster RCNN算法

&#xff08;未完成&#xff0c;待补充&#xff09; 获取Faster RCNN源码&#xff08;开源的很多&#xff09; 替换自己的数据集&#xff08;图片标签文件&#xff09; 打开终端&#xff0c;进入gpupytorch环境 运行voc_annotation.py文件生成与训练文件 E:\DeepLearningMode…

Linux配置VNC实现远程控制,提高运维效率

VNC介绍 1.1 VNC简介 VNC (Virtual Network Console)是虚拟网络控制台的缩写。它 是一款优秀的远程控制工具软件&#xff0c;可以实现远程控制计算机的功能。 1.2 VNC组成 VNC基本上是由两部分组成&#xff0c;在任何安装了客户端的应用程序(vncviewer)的计算机都能十分方便…

蓝桥杯第1390题——A Careful Approach

题目描述 如果你认为参加一个编程比赛让你感到有压力&#xff0c;那么请你想象你是一个空中交通管制员。因为人命关天&#xff0c;所以一个空中交通管制员必须在时刻变化的环境中专注于任务&#xff0c;解决不可预知的事件。 让我们将目光转向飞机的着陆流程。飞机进入目的地飞…

人事档案转出需要注意哪些方面

人事档案转出是指将员工的人事档案从一个部门、公司或组织转移到另一个部门、公司或组织的过程。这个过程需要注意以下几个方面&#xff1a; 1.法律合规&#xff1a;在进行人事档案转出前&#xff0c;要确保遵守相关的法律法规和公司内部规定。例如&#xff0c;要确保有合法的授…

vue-lazyload 图片懒加载的原理与使用

一、图片懒加载vue-lazyload是什么&#xff1f; 背景&#xff1a; 图片是非常占用页面渲染时间的&#xff0c;尤其是一些图片比较多的页面&#xff0c;过多的图片可能会造成页面的卡顿&#xff0c;降低流畅度影响用户体验&#xff0c;我们在实际开发中&#xff0c;对于处于视口…

Redis 7.0版本主从复制机制

1、引言 Redis是一个开源、高性能、内存键值存储系统&#xff0c;同时也提供了数据结构服务器的功能。它支持五种主要的数据类型&#xff1a;字符串&#xff08;String&#xff09;、哈希表&#xff08;Hashes&#xff09;、列表&#xff08;Lists&#xff09;、集合&#xff…

【TEE】内存完整性保护

Hash Functions&Merkle Tree 对读操作进行完整性检查&#xff0c;通过在加载的块上重新计算一个哈希&#xff0c;然后根据片外地址将得到的哈希与片上哈希比较。 缺点&#xff1a;不可承受的片上存储开销&#xff0c;并假设128位哈希和512位cache line&#xff0c;其开销为…

LABEL-EFFICIENT SEMANTIC SEGMENTATION WITHDIFFUSION MODELS

基于扩散模型的标签高效语义分割 摘要&#xff1a; 去噪扩散概率模型最近受到了很多研究的关注&#xff0c;因为它们优于gan等替代方法&#xff0c;并且目前提供了最先进的生成性能。扩散模型的优越性能使其成为一些应用程序的吸引人的工具&#xff0c;包括绘图&#xff0c;超…

STM32CubeIDE基础学习-新建STM32CubeIDE基础工程

STM32CubeIDE基础学习-新建STM32CubeIDE基础工程 前言 有开发过程序的朋友都清楚&#xff0c;后面开发是不需要再新建工程的&#xff0c;一般都是在初学时或者有特殊需要的时候才需要新建项目工程的。 后面开发都是可以在这种已有的工程上添加相关功能就行&#xff0c;只要前…

智能合约的编程语言

智能合约的编程语言 Solidity: https://learnblockchain.cn/docs/solidity/ 相关资料&#xff1a; https://guide.pseudoyu.com/docs/study_path/ 智能合约的技术栈 Hardhat https://hardhat.org/ Truffle https://trufflesuite.com/docs/truffle/ Remix https://hard…

基于openKylin与RISC-V的MindSpore AI项目实践

项目目标&#xff1a; 在openKylin系统上安装和配置MindSpore框架。开发一个简单的图像分类模型&#xff0c;并在RISC-V平台上进行训练和推理。根据RISC-V的特性&#xff0c;对MindSpore框架进行必要的优化。 目录 项目目标&#xff1a; 训练模型 编写训练代码&#xff0c;设…

外包干了3个月,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

Flutter App代码混淆

Flutter 应用混淆 Flutter 应用的混淆非常简单&#xff0c;只需要在构建 release 版应用时结合使用 --obfuscate 和 --split-debug-info 这两个参数即可。 flutter build apk –obfuscate --split-debug-info 命令需要指定输出调试文件的位置&#xff0c;该命令会生成一个符号映…

挑战给女神节送礼物,怎么寄快递才能快速的送到他手中呢?

马上就是三八女神节了&#xff0c;怎么样&#xff1f;你给心爱的她或者敬爱的她准备礼物了吗&#xff0c;如果已经准备好&#xff0c;你该怎么送给她呢&#xff1f;是当面送给她&#xff1f;还是通过快递打包送给她呢&#xff1f;这里推荐使用闪侠惠递寄快递发货给他吧&#xf…

SQL Server 阻止了对组件 ‘Ole Automation Procedures‘ 的 过程‘sys.sp_OACreate‘ 的访问

SQL Server 阻止了对组件 Ole Automation Procedures 的 过程sys.sp_OACreate 的访问&#xff0c;因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 Ole Automation Procedures。有关启用 Ole Automation Procedures 的详细信息&a…

防御-day6-内容安全()

一、文件过滤技术 这里说的文件过滤技术&#xff0c;是指针对文件的类型进行的过滤&#xff0c;而不是文件的内容。 想要实现这个效果&#xff0c;我们的设备必须识别出&#xff1a; 承载文件的应用 --- 承载文件的协议很多&#xff0c;所以需要先识别出协议以及应用。 文件传输…

【小白友好】LeetCode 删除并获得点数

基础题 打家劫舍https://leetcode.cn/problems/house-robber/ 小白解法 删除nums[i]就会使得所有nums[i]-1和nums[i]1的值都消失&#xff0c;手写了几个&#xff0c;发现找来找去不方便&#xff0c;还不如先排个序&#xff0c;然后这样nums[i]-1和nums[i]和nums[i]1就能靠在…

【Python】使用numpy进行神经网络激活函数算法描述

【Python】使用numpy进行神经网络激活函数算法描述 系统&#xff1a;macOS 10.14.5 IDE&#xff1a;PyCharm 2018.2.4 一、What 1.1 NumPy NumPy(Numerical Python) 是 Python 语言的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供…

基于灰狼算法GWO的城市三维无人机路径规划(复杂地形三维航迹路径规划)

摘要 本文提出了一种利用灰狼算法GWO来解决城市环境下无人机三维路径规划问题的方法。这种方法将复杂的无人机航迹规划任务转化为一个优化问题&#xff0c;然后运用灰狼算法GWO来解决这个优化问题。灰狼算法GWO是一种模拟灰狼种群捕猎行为的优化算法&#xff0c;它具备强大的全…

2024年第一届CS2major,新胶囊即将发行,需要提前做哪些布局

2024年第一届CS2major&#xff0c;将会在3月17日哥本哈根开始。 所以&#xff1a; 1、新的胶囊大概率会在3月10日左右发布。 2、网传战队挂坠&#xff0c;不知道是否会出现&#xff1f;&#xff08;原本出现过战队布章包&#xff0c;由于销量太差&#xff0c;第二届就取消了…