Linux小黑板(7):再谈动静态

news2024/11/16 0:16:59

"我看到,久违的晴朗啊"

一、什么是动静态库

在本栏目前面的篇幅也提到过这个概念,因此本小节就小小地回顾一番。

在linux下:
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个库的名称为:去掉前缀lib去掉后缀.a(.so)

在windows下;
静态库(.lib)
动态库(.dll)

二、如何制作静态库

(1)理解.o文件

在开介绍如何制作动静态库之前,我们不得不提一嘴

程序从代码编译生成可执行程序分为四个阶段:
预处理 ---> 编译 ---> 汇编 --->链接
分别对应GCC编译器选项的 -E -S -C
生成的文件分别为: .i(头文件展开源码) .s(汇编码) .o(可重定位的二进制目标文件)

我们写了一个my_add.c my_sub.c 功能是实现加法和减法。

gcc -c + file.c 可以生成同名的 file.o 可重定位二进制文件
gcc -o 目标文件 源文件

链接后形成可执行程序!这不就是我们平常只需要使用GCC直接就可以生成 可执行程序吗?

只不过我们手动对.o文件进行了链接;

因此,如果不想给对方提供自己的源文件,源代码,那我是否提供一个.o文件就行了呢?是的!

未来我们可以为用户提供.h(有什么方法),.o(方法的实现)。

但是,在实际中不仅仅如我们上面的例子,那少得可怜的.o\.h文件。如C库中的printf、scanf、max、pow……于是,我们就会尝试将所有的".o文件"打一个包,给用户提供这个包即可。

因此,库文件的本质是.o文件的集合。

(2)如何打包静态库

1.生成.o文件集合

liunx中的ar命令:
ar命令是Linux的一个备份压缩命令,可以创建、修改备存文件(archive),或从备存文件中抽取成员文件。备存文件以一定的结构打包一个至多个其它文件(即成员文件),且成员文件的内容、模式、时间戳等信息将被保存在备存文件中。

参数(例举):
r :在库中插入模块(替换)。
当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar 显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
c :创建一个库。

Makefile;

libmath.a:my_add.o my_sub.o
    ar -rf $@ $^                    #静态库打包生成集合文件
my_add.o:my_add.c
    gcc -c my_add.c -o my_add.o

my_sub.o:my_sub.c
    gcc -c my_sub.c -o my_sub.c


#发型版本
.PHONY:output
output:
    mkdir -p mylib/include   
    mkdir -p mylib/lib
    cp -rf *.a mylib/lib
    cp -rf *.h mylib/include

.PHONY:clean
clean:
    rm -rf *.o libmath.a mylib mymath

于是我们也就制作了一个静态库了。

2.压缩与解压

我们也可以对mylib进行压缩。

tar -cf archive.tar foo bar
# Create archive.tar from files foo and bar.
tar -tvf archive.tar
# List all files in archive.tar verbosely.
tar -xf archive.tar
# Extract all files from archive.tar.

压缩;

解压;

(3)如何使用静态库?

此时我们用gcc进行编译;

但编译器找到不到路径,就算我们mylib里有那些方法的声明。

此时我们给编译器带上选项"-I" 指定寻找,但是它拿到了声明,但是没有方法的实现。

我们带上"-l" 指定库名!但是为什么仍然ld失败呢? 因为,库文件的名字:去掉前缀去掉后缀!

此时,我们打包的静态库终于可以被使用了~

(4)系统库路径

这不对啊!我们平常使用gcc\g++的时候都没有带上这些库路径和库名称。上面的实验则证实了,一旦要连接第三方库,一定需要指定库名称。然而事实上是,gcc\g++只会认识它们自己的C\C++标准库,并且gcc\g++的链接行为,默认是动态链接的。

这也是为什么我们上面的可执行程序是"dynamically linked"

系统include;

此时我们将my_add.h \ my_sub.h拷贝进这个路径下;

系统lib;

我们把自己的lib库拷贝进行库中;

我们在用gcc编译;

由此,我们不仅仅完成了对静态库的打包、使用。

同样也对yum有了一个新的理解。当我们通过yum源,在网上获取数据,下载下来的库、包,本质就是将文件的内容,拷贝赋值到系统库、路径下。这就叫做安装!

三、如何制作动态库

(1)制作动态库

制作动态库gcc可以提供了制作动态库的操作;

gcc -FPIC:生成的.o文件是位置无关的
gcc -shared lib.so file.o

此时我们生成的libmymath.so是一个动态链接的共享文件;

(2)如何使用动态库

我们也就根刚刚一样,去编译这个文件。

但是我们会发现就算生成了可执行程序,但是根本运行不起来! 我不是都告诉了库的头文件和.o文件吗??

我们是给谁的说的? gcc~
可是当程序被编译完后,还和gcc有关系吗? 没有! 那么是谁找不到呢? 操作系统!
当程序运行起来,OS需要找到动态库并将其中的代码 loading进程序内。而你的库没有在系统路径下,Shell 与 OS根本找不到!

1.环境变量搜索(LD_LIBRARY_PATH)

我们此时就需要导入 第三库的路径和lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wsy/workfile_new/lesson22/test

我们此时运行程序,也就没有行了~

但是这种环境变量的方法,仅仅是用于测试可行。仅仅是在本次登录有效。

2.etc配置

如何保证永久有效呢?直接拷贝入系统路径下,这显然是不用再多说的,不过也可以借用etc进行配置;

cd /etc/ld.so.conf.d

我们随便创建一个文件,并把动态库的路径写入进去。

ldconfig 更新

于是就可以找到这个动态库了。

3.软链接

当找动态库的时候,默认也会在当前路径,同级目录寻找。但注意,需要软链接是,是库文件名。

我们同样也可以将软链接 建立在系统路径下。效果也是一样。也就不在此多说了。

四、如何理解动静态库?

(1)静态库

(2)动态库的加载

由此,可见,进程地址空间的概念是操作系统最重要的!它不止可以看到进程内部自己的资源,也可以访问外部的库资源等。

总结:

  • linux下静态库以.a结尾,动态库以.so结尾。

  • 库的本质是一堆.o可重定位二进制文件的集合。

  • 静态库打包 ar -rc

  • 需要链接第三方库: -I(指名include) -L(库) -l(库名)

  • gcc有一套制作动态库的方法 gcc -fPIC(生成位置无关 这与后面加载映射关系很大) gcc -shared生成动态库

  • 告诉gcc动态库 != 告诉OS。有三种方法可以实现OS找到动态库在哪里:1.LD_LIBRARY_PATH 2.etc配置 3.软链接

  • 动静态库加载细节

本节到此结束,感谢你的阅读,

祝你好运~向阳而生

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

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

相关文章

【npm报错】解决invalid json response body at https://registry.npmjs.org

报错信息: npm ERR! code FETCH_ERROR npm ERR! errno FETCH_ERROR npm ERR! invalid json response body at https://registry.npmjs.org/riophae%2fvue-treeselect reason: Invalid response body while trying to fetch https://registry.npmjs.org/riophae%2f…

从粪便菌群移植到下一代有益菌:Anaerobutyricum soehngenii为例

谷禾健康 我们知道,肠道微生物群对人类健康和福祉很重要,调节宿主代谢,塑造免疫系统并防止病原体定植。 通过粪便微生物群移植(FMT)恢复平衡多样的微生物群,已成为研究疾病发病机制中微生物群因果关系的潜在…

Spring Cloud Gateway 之限流

文章目录一、常见的限流场景1.1 限流的对象1.2 限流的处理方式1.3 限流的架构二、常见的限流算法2.1 固定窗口算法(Fixed Window)2.2 滑动窗口算法(Rolling Window 或 Sliding Window)2.3 漏桶算法(Leaky Bucket&#…

CSS3属性之text-overflow:ellipsis详解

1.text-overflow: 默认值:clip; 适用于:所有元素 clip:当前对象内文本溢出时不显示省略标记(…),而是将溢出部分裁剪。 ellipsis:当对象内文本一处时显示省略标记(…)。 当然这还是不够的,需要加点调料才能出现效果: 那就是配合 overflow:hidden white-space:…

高级树结构之红黑树初识

文章目录一 红黑树简介二 探究变色、旋转操作的时机三 总结一 红黑树简介 通过在插入几点时维护数的平衡,这样就不会出现极端情况,使得整棵树的查找效率急剧降低。但是这样造成系统开销过大,因为一旦平衡因子的绝对值超过一就失衡&#xff0…

iOS 界面尺寸居然跟实际机型不符!

0x00 前言 日常搬砖过程中,一条日志,让我对手里的 iPhone 6 Plus 产生了怀疑? 这是 6P,怎么尺寸变成 6 了呢? 0x01 对比 手机连上电脑,通过 Xcode 查看 Window 菜单:Devices and Simulators …

Insight Enterprises EDI 855 采购订单确认报文详解

本文着重讲述Insight EDI项目中Insight回复给采购商的X12 855报文(采购订单确认)。 在此前的文章如何读懂X12报文中,我们对X12报文的结构已经做了详细的介绍,本文将带大家深入了解X12 855采购订单确认报文。 下图为Insight X12 …

单绞机张力开环控制(绞臂行星差速机构)

PLC的开环和闭环张力控制算法,可以参看下面的文章链接: PLC张力控制(开环闭环算法分析)_plc张力控制程序_RXXW_Dor的博客-CSDN博客里工业控制张力控制无处不在,也衍生出很多张力控制专用控制器,磁粉制动器等,本篇博客主要讨论PLC的张力控制相关应用和算法,关于绕线机的…

Java学习之final关键字

目录 一、基本介绍 二、使用final的四种情况 第一种 第二种 第三种 第四种 三、细节 第一点 第二点 第三点 第四点 第五点 第六点 第七点 第八点 第九点 四、练习 第一题 第二题 分析 一、基本介绍 final:最终的,最后的 final 可以修饰类…

图形编辑器:旋转选中的元素

大家好,我是前端西瓜哥。 最近更文比较少,是因为本人在做个人开源项目,用 Canvas 做一个设计工具,做个乞丐版 figma。期间遇到了不少问题,在这里记录一下。 今天开始会恢复高频更新的,一两天一更。内容主…

Linux网络服务管理防火墙详解端口问题

每次配置访问服务器都会一团迷雾,今天来尝试弄清楚同时借鉴一下大佬的博文当做笔记 文章目录防火墙简介一、防火墙基础二、iptables防火墙策略iptables 命令格式:iptables案例1.查看开放的端口2.开放端口(此处以80端口为例)3.关闭…

超级详细的PMP复习方法,3A拿下考试不发愁!

如果问我是怎么一次性通过考试的,那绝对不只是运气,没有一点基本的实力怎么有底气通过考试呢,所以今天我们不讲什么刷题技巧,基础不牢靠将技巧都是没用的,今天我们先讲讲要怎么巩固基础,给到朋友们分享一些…

kaggle平台学习复习笔记 | 特征工程

目录数值字段roundBox/Bins类别字段onehotLabelEncoderOrdinal EncodingBinaryEncoderFrequency/Count EncodingMean/Target Encoding日期字段特征筛选feature_importances_利用方差利用相关性利用线性模型迭代消除排列重要性(Permutation Importance)特征工程决定了模型精度的…

MATLAB-RBF神经网络例1

采用所描述的系统中﹐假设真实质量为m2,在仿真中,初始值为,采用的自适应律为:设定参数为y0.5,10,25,6,分别设定参考位置为r(t)0,r(t )sin(4t) ,初始条件为,。图1.1和图1.2为指令r(t)0时控制效果,图1.3和图1.4为指令r(t)sin(4t )时的控制效果。…

verilog学习笔记- 12)触摸按键控制LED灯实验

目录 简介: 实验任务: 硬件设计: 程序设计: 下载验证: 简介: 触摸按键主要可分为四大类:电阻式、电容式、红外感应式以及表面声波式。根据其属性的不同,每种触摸按键都有其合适的使用领域。 电阻式触摸按键&#…

响应式与观察者模式

什么是响应式?响应式 是Vue 最独特的特性之一,是非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。我们也叫他双向绑定。如果想要更改视图,只要直接更改对应属性的值即可&#xff…

从隔壁老王开始的信号处理入门

诸神缄默不语-个人CSDN博文目录 我是从GNN被扔到NLP然后又做起了GNN现在又被喊去搞时间序列分类,所以现在才开始看信号处理(因为我开始做GNN以来,GNN就以图域而非谱域为主了,所以那时我没怎么看过信号处理)。 所以写个…

RabbitMQ消息队列(三):任务分发机制

在上篇文章中,我们解决了从发送端(Producer)向接收端(Consumer)发送“Hello World”的问题。在实际的应用场景中,这是远远不够的。从本篇文章开始,我们将结合更加实际的应用场景来讲解更多的高级…

jetson nano上编译与使用西门子PLC通讯库snap7

文章目录一.西门子snap7介绍二.西门子S7通讯介绍三.jetson nano编译snap7库四.Qt Cmake导入snap7库五.snap7主要函数说明1.与PLC建立连接2.读写PA区变量3.读写MK区变量六.通讯程序示例一.西门子snap7介绍 Snap7 是一个基于以太网与S7系列的西门子PLC通讯的开源库。支持包括S7系…

2023美赛数学建模ABCDEF题思路模型代码

占个位置吧,开始在本帖实时更新赛题思路代码,文章末尾获取! 持续为更新参考思路 赛题思路 会持续进行思路模型分析,下自行获取。 A题思路: (比赛开始后第一时间更新) B题思路:…