【Linux】软硬链接 / 动静态库

一. 软硬链接

1. 硬链接

硬链接(hard link) 可以将它理解为原始文件的别名, 和原始文件使用相同的 inode 编号和 data block.(inode 是文件在该磁盘分区内的唯一标识, 记录着文件的属性等内容; data block 是文件的内容)

可以使用 ln 指令为文件创建一个硬链接.

ln log.txt link.hard

在这里插入图片描述
当创建一个新的硬链接时, 该文件的硬链接数就会加 1; 删除一个文件时, 该文件的硬链接数就会减 1; 只有硬链接数为 0 时, 才会彻底删除该文件.

实际上, 硬链接文件和原文件是同一个, 所以 inode 和属性会和原文件相同, 并且当一个文件更改内容或属性时, 其他的文件也会随之改变.
在这里插入图片描述

  • 注:
    用户不可以使用硬链接 链接目录, 操作系统禁止这样的行为;
    硬链接不能跨分区对文件进行链接.(inode 只在分区内唯一)

2. 软链接

软链接 类似 Windows 系统下的快捷方式, 是一个的全新的文件, 并且文件类型为 ‘l’ (链接属性), 内容仅包括所含链接文件的路径名字.
所以软链接能够链接目录, 也能跨区链接; 但当删除或移动原始文件 或路径失效后, 链接文件也随之失效.

使用 ln -s 选项创建软链接

ln -s log.txt link.soft

在这里插入图片描述
软链接的文件属性, inode 和原文件都不相同, 并且 软链接文件会指向 (->) 源文件.

3. unlink

使用 unlink 指令可以删除链接文件, 也可以删除普通文件.(rm 指令类似, rm 指令也可以删除链接文件)

unlink /*file_name*/

在这里插入图片描述

4. 目录的硬链接

当新创建一个目录时, 硬链接数默认为 2.
在这里插入图片描述
因为一个新创建目录时不只在当前目录下创建了 test_dir 和 inode 的映射关系, 在 test_dir 目录中还会创建隐藏的 . 和 inode 的映射关系, 所以硬链接数会增加.
在这里插入图片描述
若在当前目录下再新建一个下级目录, 那么当前目录的硬链接数就会加 1, 因为下级目录中的 **..**也是当前目录的一个硬链接.

而操作系统不允许用户创建目录的硬链接, 是因为操作系统会将用户创建的目录认为是下级目录, 在遍历搜索文件等情况下, 会造成环路问题.

二. 动静态库

静态库是 文件在编译链接时使用静态链接, 把需要的库文件全部拷贝至可执行文件中, 可执行程序在运行时不依赖其他文件; 在 Linux 下后缀为 “.a”, 在 Windows 下后缀为 “.lib”.

动态库也被称为共享库, 可执行程序会在运行时动态链接 动态库, 多个可执行程序可以同时调用动态库; 动态库在 Linux 下后缀为 “.so”,在 Windows 下后缀为 “.dll”.

1.1 静态库制作

静态库就是将实现方法的源文件打包为一个文件.

先将源文件编译为 .o 文件
在这里插入图片描述
之后使用 ar 指令打包即可.

//ar [选项] [库名] [依赖文件]
ar -rc libFunc.a Add.o Sub.o	// -r replace, -c create  // -rc 创建或替换库文件

在这里插入图片描述

1.2 静态库使用

由于编译器默认不识别第三方的库文件, 直接编译会报错.
在这里插入图片描述
所以编译时需要将库文件的路径和文件名一起作为参数传入 gcc/g++ 中.

-I(大写 i) 表示头文件的路径
-L 表示库文件的路径
-l(小写 L) 表示库文件名
在这里插入图片描述

也可以直接将创建的头文件和库文件安装至系统目录中, 但并不推荐, 会污染系统的库目录.

2.1 动态库制作

动态库的制作和静态库类似, 不过动态库编译的源文件需要使用 -fPIC 选项, 表示产生位置无关码.
在这里插入图片描述
动态库打包依旧使用 gcc/g++, 使用 -shared 选项即可(表示生成共享库格式).
在这里插入图片描述

2.2 动态库使用

但由于动态库是运行时动态链接动态库的, 运行时会找不到动态库; 而静态库是编译时将静态库拷贝至可执行程序中的, 所以运行时不依赖文件.
在这里插入图片描述
解决方法:

  • 拷贝动态库的软链接或动态库本身 至 /lib64/ 目录下;
  • 设置环境变量 LD_LIBRARY_PATH, 可以将第三方动态库路径添加至此环境变量中(临时方案);
//										动态库路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hhhhhan/Program/test1

在这里插入图片描述

  • 设置配置文件, 在 /etc/ld.so.conf.d/ 目录中的都是动态库配置文件, 可以在该目录创建配置文件 xx.conf (文件中存储动态库的路径), 使用 ldconfig 指令加载配置文件.
echo /home/hhhhhan/Program/test1/ > Test.conf
sudo mv Test.conf /etc/ld.so.conf.d/
sudo ldconfig

3. 动态链接原理

在可执行程序编译完成后, 可执行程序内库函数的地址并不是真正的地址, 而是库函数在动态库中的偏移量(相对地址), 是通过位置无关码 fPIC 生成的.

当可执行程序开始运行时, 若动态库没有在内存中, 操作系统会先将动态库加载至内存中; 然后通过页表建立映射关系, 将动态库加载至共享区中, 获得的动态库起始地址;

当可执行程序调用库函数时, 可执行程序会通过 动态库起始地址 + 偏移量 调用库函数.
在这里插入图片描述

动态链接解决了静态库空间浪费的问题, 可执行程序只需要保存库函数的偏移量, 在运行时通过动态库加载至共享区中的虚拟地址和页表的映射, 就可以调用库函数;
使得内存中只需要存在一份动态库, 就可以同时被多个可执行程序使用.

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-06 16:24:05       75 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-06 16:24:05       80 阅读
  3. 在Django里面运行非项目文件

    2024-04-06 16:24:05       64 阅读
  4. Python语言-面向对象

    2024-04-06 16:24:05       75 阅读

热门阅读

  1. LeetCode 1365. 有多少小于当前数字的数字

    2024-04-06 16:24:05       36 阅读
  2. 位运算-力扣67. 二进制求和

    2024-04-06 16:24:05       32 阅读
  3. Linux查看日志的几种方法

    2024-04-06 16:24:05       27 阅读
  4. Python数据分析十六

    2024-04-06 16:24:05       36 阅读
  5. 【NS-3学习(三)】可视化NetAnim使用笔记

    2024-04-06 16:24:05       35 阅读
  6. 数据结构与算法实验9-图的应用(最短路径)

    2024-04-06 16:24:05       35 阅读
  7. [LeetCode][LCR190]加密运算——全加器的实现

    2024-04-06 16:24:05       43 阅读