Linux的基础IO:软硬连接 动态库 静态库

2024-05-08 16:28

本文主要是介绍Linux的基础IO:软硬连接 动态库 静态库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

软硬连接

硬链接的作用

静态库

制作静态库

安装自定义静态库

动态库

制作动态库

协助OS查找动态库的五种方法

总结 

动态库加载


软硬连接

创建硬链接指令:ln 目标文件 链接者

创建软链接指令:ln -s 目标文件 链接者

删除链接指令:rm 链接文件名

结论:

  1. 软链接是一个独立的文件,有独立的inode number
  2. 硬链接不是一个独立的文件,与目标文件共享inode

结论:软链接包含目标文件所对应的路径字符串(路径具有唯一性,OS进行路径解析找到对应的文件),等价于windows中的快捷方式

结论:软链接不仅可以链接可执行程序,还可以链接普通文件

现象:删除目标文件仍然可以使用硬链接,硬链接的除了硬链接数改变其余相关属性不变

结论1:建立硬链接就是在指定目录下,添加一个新的文件名和inode number的映射关系

结论2:硬链接数就是文件的磁盘级引用计数,即有多少个文件名字符串通过inode number指向同一个的inode(将inode number抽象理解成指针)

注意事项:

1、当只有i_nlink(新创建的硬链接数)及i_count(文件创建初始的计数)都为0的时候,这个文件才会真正被删除(这也是为什么我们在rm file_target1.txt令i_count归零后因为i_link仍为1所以还可以找到inode number对应的文件的原因) 

2、硬链接就是同一个文件使用了多个别名(对引用的目标文件可进行读写操作),它们共同“指向”同一个文件的数据块

3、定位一个文件只有两种方式:

  1. 通过路径,当然最终也是要通过inode number(软链接可以实现)
  2. 直接找到目标文件的inode number(硬链接可以实现)

4、软硬链接存在的目的就是为了让我们快速找到目标文件

硬链接的作用

结论:

  • 任何一个目录刚开始创建的时候,硬链接的引用计数一定为2
  • 在目录中创建一个子目录则该目录的硬链接数自动+1
  • 一个目录中的所有子/孙子...目录数之和 = A的硬链接数 - 2 

作用1:构建Linux的路径结构,让我们可以使用.和..来进行路径定位

作用2:一般用硬链接做文件备份(前面先删除普通文件后删除硬链接的例子可以证明,此外有些资源官方不可能为用户每个人都拷贝一份,只需要为用户提供一个与该资源的硬链接,多个用户就可以通过该硬连接访问,当然实际情况会比这更复杂)

问题:为什么不能创建硬链接?

 解释:如果可以在lesson23目录下建立一个指向root目录的硬链接,当尝试寻找lesson23目录中的某个.txt文件时,搜索过程中找到了该硬链接,就会重新进入root目录寻找,从而造成路径循环,.和..可以循环的原因是Linux涉及时已经做好了处理,而普通用户在使用时没做特殊处理(比如符号链接、联合挂载等方式)就不能为目录建立硬链接

静态库

基本概念:Linux中.a结尾的库是静态库(自己的笔记本电脑单人独享),.so结尾的是动态库(相当于网吧,多个共享);Winodws中的.dll结尾的是动态库,.lib结尾的是静态库

s查找可执行程序依赖的库指令:ldd 可执行程序名

结论:/lib64/libc.so.6是一个软链接 

制作静态库

前提:头文件是一个方法的使用手册,提供函数声明,.o提供二进制的实现,我们只需要补上一个main函数,调用头文件提供的方法,然后由gcc将所有.o进行连接,最后形成可执行

        如果不想把自己写的底层方法的源代码发给室友防止他抄袭,可以将源代码变为二进制的目标文件后与自己写的底层方法的使用手册发给室友,此时室友只需要将自己设计的main.c文件也变为目标文件.o,然后:就可以经gcc将多个.o文件链接从而得到一个可执行程序

gcc main.o mymath.o mystdio.o myexe

        可是如果要将很多的.o文件发给室友,室友在使用时不小心删除了某一个.o文件那么室友在将所有文件进行gcc的时候就会出错,那么为了防止室友在操作过程中不小心将某个.o文件删除,我们可以在发给室友前将所有.o文件进行打包,然后再将打包后的结果传递给室友

打包.o文件指令:ar -rc 包文件 被打包的文件

  • ar是gnu归档工具,rc表示(replace and create)

查看静态库中的目录列表指令:ar -tv 静态库文件

  • t:列出静态库文件
  • v:列出详细信息

结论:库文件的本质就是将多个.o文件进行打包

原因:提高开发效率,用户不需要管底层的方法实现,可以直接使用

安装自定义静态库

开发者将自己的操作手册和方法实现全部放入一个目录中,并由室友”模拟“下载该目录:

        如果室友想不gcc其它.o文件直接gcc自己写的文件,可以直接将这些文件放入系统的文件中,这样直接gcc main.c就可以生成可执行程序了,存入之后就可以将安装包mylib删除了: 

此时室友main.c所包含的头文件可以从""变为<>了: 

  • #include <> :表示引用标准库头文件,编译器会从系统配置的库环境中去寻找
  • #include "":一般表示用户自己定义使用的头文件,编译器默认会从当前文件夹中寻找,如果找不到,则到系统默认库环境中去寻找
  • linux下C和C++默认库环境路径:/usr/include

实际运行时,gcc/g++编译器并不认识第三方添加到系统文件中的库文件,需要额外添加一个选项-l:gcc main.c -l libmyc.a(两个l相邻),但是此时仍然会编译报错,这是因为libmyc.a去掉前后缀得到的myc才是编译器可以识别的,所以最终的命令是:gcc main.c -l myc,但实际上我们十分不建议将自己编写的库文件放入系统中,建议趁早删除:

sudo rm /usr/include/mysyio.h
sudo rm /usr/lib/libmyc.a

结论:安装库文件就是将库文件放入对应的系统目录中

如果不下载到系统文件中,可以使用指令指明要参与编译的.h和.o文件:

  • 头文件指明路径不需要指明具体头文件名称,是因为在main.c中就有了#include<头文件>,在-I 选项的帮助下gcc会先去指定路径下寻找头文件再去系统文件中寻找,颠倒寻找顺序
  • 如果连自定义头文件的路径都不想指明,可以将main.c文件中的<>换为" "

补充:有static修饰时,强制gcc全部使用静态链接,无static修饰时有动态链接就用动态链接,没有动态链接就用静态链接

动态库

制作动态库

基本概念:动态库的制作也要将头文件和方法文件变为.o文件,但是在gcc -c main.c生成目标文件前还要加上一个-fPIC选项,该选项的意思是产生位置无关码

打包动态库文件指令:gcc  -shared *.o -o libmyc.so

  • 为了防止gcc在尝试将这些.o文件形成可执行程序时报错,需要加上shared表示生成共享库格式,即我们想要让gcc将这些.o文件生成一个动态库而不是可执行程序

同样的可以用下面的之类指定头文件路径、库文件所在路径、库文件名称后运行程序:

gcc main.c -I mylib/include/ -L mylib/lib -l myc 

虽然这样可以编译链接后生成可执行程序,但是执行可执行程序时会报错:

解释:因为我们告诉的是编译器gcc这些文件的路径以及名称,但是在执行可执行程序是由OS进行的,OS还并不知道这些信息,在程序运行时OS要找到并加载动态库到可执行程序中然后才能运行程序(动态库只是说和可执行程序间建立关联并未加载到可执行程序中),而静态库没有这一问题的原因是,在编译期间已经将库中的代码拷贝到我们的可执行程序中,程序的运行就和库没有关系了(编译时告诉gcc的是可执行程序与动态库的依赖关系)

协助OS查找动态库的五种方法

1、直接将动态库放入系统文件中(不建议)

2、建立软链接

3、命令行导入环境变量

LD_LIBRARY_PATH是一个用于指定动态链接库的搜索路径的环境变量

4、修改.bashrc配置文件,使对环境变量的修改得以永久保存(不推荐)

5、/etc/ld.so.conf.d路径下新增动态库搜索的配置文件:ldconfig

后两个具体实现方法在26、20~30分处,节省时间不做过多叙述

使用外部库的操作在26、50分处

总结 

1、如果我们要使用别人的库,别人应该给我们提供一批头文件和一批库文件(.so和.a),我们在使用第三方库文件生成可执行程序时要参考以下格式写:gcc main.c -l 动态库文件名(记得去掉前后缀)

2、gcc在不使用static选项时,默认使用动态库,如果在多个库文件中提供了一个.a且未使用static选项,则gcc静态链接.a,动态链接其它库

3、为保证使用statci选项时不出下图中的报错,我们链接提供的任何库文件都要包含静态库版本

4、库的加载与静态库无关, 静态库在编译时就已经加载到程序中,后续要考虑的就是程序的加载

动态库加载

基本概念:动态库.so、静态库.a和可执行程序本质是都是磁盘上的文件(使用文件就要提供它们的路径)

补充内容:Linux中形成的可执行程序的格式是ELF格式,程序编译完后形成的二进制文件中的二进制内容是有固定格式的,固定格式中一定要有ELF格式的可执行程序的头部,而头部中又会有很多可执行程序的属性 

问题:在编写代码时起的变量名在程序编译后还存在吗?

解释:不在了,都变成了地址

问题:可执行程序编译成功后,加载运行前,它的二进制代码中有“地址”吗?

解释:

结论:可执行程序编译后会形成很多汇编语句,且每条汇编语句都有它的地址,这些地址都是虚拟地址,在平坦模式 + 绝对编址的情况下虚拟地址等价于逻辑地址

问题:如何对这些汇编语句进行编址呢?

解释: 编址方式分为绝对编址和相对编址:

后续具体内容在26、1:30~2:14处,这里可以提供结论:

1、采用动态链接的进程在创建后,会初始化地址空间,等到进程执行时,CPU就会依据地址信息找到main函数的入口

~over~

这篇关于Linux的基础IO:软硬连接 动态库 静态库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/970833

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念