【Linux】软硬链接与动静态库(理解软硬链接的特点及使用场景、如何建立动静态库与使用第三方库)

本文详细介绍了Linux系统中的软链接、硬链接概念,以及它们的特点和功能。同时对比了静态库和动态库的区别,包括编译链接方式、内存占用和库的使用方法。
摘要由CSDN通过智能技术生成

一、软链接

1.1 如何建立软链接
//建立软链接  -s代表soft
ln -s 目标文件名 链接文件名

//删除软链接
rm 链接文件
或
unlink 链接文件

1.2 软链接的特点与功能

通过ls -i指令可以查看文件的inode编号

可以看出目标文件与软链接文件各自有自己的inode,所以软链接是一个独立的文件

查看目标文件与查看链接文件的内容是相同的,这个类似于快捷方式的功能

所以在项目中当我们需要访问一个路径很深的文件时,我们可以建立一个软链接,这样访问文件就不需要每次都输入完整的路径了

当我们删除目标文件时,会发现软链接失效了,这是因为软链接的内容保存的是目标文件对应的路径字符串,当目标文件被删除时,软链接也就失效了

二、硬链接

2.1 如何建立硬链接
//建立软链接  ln默认为硬链接
ln 目标文件名 链接文件名

//删除软链接
rm 链接文件
或
unlink 链接文件

2.2 硬链接的特点与功能

可以发现硬链接与目标文件的inode编号是相同的,所以硬链接不是一个独立的文件,其使用的是目标文件的inode,并且我们发现当建立硬链接后,文件中间的有个数字从1变成了2,这个数字类似于引用计数,表示与该inode编号映射的文件的个数

所以硬链接就是文件名与inode编号的一个映射关系,建立硬链接的本质就是在指定目录下,建立一个新用户名与inode编号的映射关系

当删除目标文件时,硬链接还可以正常使用,只是引用计数会减1,对文件建立硬链接然后删除目标文件就相当于对文件重命名

#硬链接的功能:

1.构建Linux路径结构(.与..)

当新建一个文件其引用计数是1,因为只有一个文件名与inode编号对应,而当建立一个目录,其引用计数是2,这是因为每个文件默认有两个名字为 . ..的文件,.对应的是当前目录,所以新建一个目录其引用计数必定是2,当在目录中创建子目录时(仅父子关系),父目录的引用计数也会加1,因为子目录的..对应父目录,所以我们也可以通过查看目录的引用计数,来判断该目录下有几个子目录

2.做文件的备份

当对目标文件建立硬链接后,若误删目标文件,我们也可以通过硬链接找回,所以硬链接可以做文件的备份

三、动静态库

3.1什么是动静态库

        静态库和动态库是计算机程序开发中两种不同的库类型,它们都是预先编译好的二进制代码集合,用于提供可重用的功能模块给其他程序调用。

#静态库:
静态库在链接阶段会被完整地加入到最终生成的可执行文件中。当编译器在创建一个程序时,如果程序引用了静态库中的函数或对象,那么静态库中的相关代码会被复制并整合到该程序内部。因此,静态链接后的可执行文件包含了程序运行所需的所有库代码,不需要在运行时依赖外部文件。静态库常见的扩展名有 `.a`(Unix/Linux 系统)或 `.lib`(Windows 系统)。

#动态库:
动态库(也称共享库或DLL - 动态链接库,在Windows系统中)则在程序运行时加载,并且多个程序可以共享同一份库代码。这意味着,动态库并不被直接合并到可执行文件中,而是作为独立的文件存在(扩展名为 `.so` 在Unix/Linux系统中,`.dll` 在Windows系统中)。当程序启动时,操作系统根据程序内存储的引用信息,将动态库加载到内存中,并让程序通过某种机制(如符号查找)来调用库中的函数或数据。这样做的好处是可以减少磁盘空间占用和内存开销,同时方便更新库文件而不必重新编译连接依赖它的所有程序。

总结来说,静态库的特点是编译时链接、代码体积大但独立运行,而动态库的特点是运行时链接、节省资源但依赖环境,当库被删除时,程序就跑不起来了

3.2 静态库

 如何建立与使用静态库

以如下四个文件举例:

Add.h:

#pragma once
#include<stdio.h>
int add(int a,int b)

Add.c:

int add(int a,int b)
{
   return a+b;
}

Sub.h:

#pragma once
#include<stdio.h>
int sub(int a,int b)

Sub.c:

int sub(int a,int b)
{
   return a-b;
}

当我们写了一份代码需要给别人,但是不想让他知道源代码是什么,我们可以将所有的.c文件先编译成.o的二进制文件,在给他提供相应的头文件信息,这样别人就可以使用我们的程序而不知道我们的代码了

但是这样操作有很大的局限性,如果我们的代码有几百个头文件,几百个.o文件,用户必须将所有的.o文件放到他的目录下,少一个可能程序就跑不起来了,如果将头文件与实现封装成一个库,那这样的问题就解决了

如何建立一个静态库:

1.先将所有的.c文件以仅编译不链接的方式形成.o文件

gcc -c xxx.c
(会默认形成一个同名的.o文件)

2.使用ar命令形成静态库,静态库名称一般以lib开头.a结尾

ar -rc libmyc.a *.o

ar:gnu归档工具

-r(replace):若静态库中的文件有所更新,就替换为新文件

-c(create):若静态库中的文件更新后,不存在某些文件,就建立这些文件

3.第二步其实就已经形成静态库了,但是为了方便管理,可以将对应的头文件也封装到一个include目录(名字随意)下,并将libmyc.a与include在封装到一个mylib文件中,这样一个第三方静态库就建立好了

如何使用第三方静态库:

方法一:

将第三方的头文件与库文件加载到系统的库搜索路径中

zyq@iZf8z3j2ckkap6ybtz8qseZ:~/mydir$ sudo cp mylib/include/*.h /usr/include/
zyq@iZf8z3j2ckkap6ybtz8qseZ:~/mydir$ sudo cp mylib/lib/*a /lib64

若此时直接编译main文件,会发现找不到add与sub函数,这是因为gcc/g++默认认识系统原本的库,而libmyc.a是第三方库,gcc不认识它,所以就找不到库中方法的实现

在使用第三方库时,需要用到 -l 选项标识自己用的库文件名(库文件名默认是去掉lib前缀和.a后缀)

方法二:

利用选项

  • -I:(大写的I) 指明用户自定义头文件的路径
  • -L:指明用户自定义库的路径
  • -l:(小写的L)指明引用到的库文件

3.3 动态库

如何建立动态库

1.首先将.c文件编译为.o文件,与静态库的方式不同的是需要加一个 -fpic(产生位置无关码(position independent code) )的选项

gcc -fpic -c Add.c Sub.c

2.将.o文件封装成动态库

  • shared: 表示生成共享库格式
  • 库名规则:libxxx.so
  • 不需要使用ar指令,gcc/g++会默认生成动态库
gcc -shared -o libmyc.so *.o
如何使用动态库

我们将形成的动态库与静态库放到一起,然后编译一下,会发现编译成功,但是可执行程序不能正常运行,如果我们加以一个-static的选项,强制使用静态库链接,发现程序可以正常执行,这说明当静态库与动态库同时存在时,编译优先使用动态库

那为什么使用静态库程序就可以运行,使用动态库就不可以呢?

【解释】:静态库在编译时就将代码加载到文件中了,运行时就与静态库没有关系了,我们通过-I -L等选项提供的路径告诉的是编译器,但是没有告诉操作系统我们的库在哪里,所以可以编译成功但是不能执行,动态库使用需要在运行时将库找到并加载

解决方法:

1.拷贝.so文件到系统共享库路径下, 一般指/usr/lib(不推荐,使用多了会造成污染)

2.在系统共享库路径下创建动态库的软链接

3.命令行导入环境变量:在LD_LIBRARY_PATH环境变量后加入动态库的绝对路径

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zyq/mydir/dir/mylib/lib

ps.这种方法重启xshell就失效了

4.修改.bashrc文件,加上动态库的绝对路径,让环境变量永久生效

5.在/etc/ld.so.conf.d目录下配置文件,并加载

以root身份进入/etc/ld.so.conf.d目录中,创建一个以.conf为后缀的文件,将动态库的路径保存到该文件中,并利用 ldconfig 指令让配置文件生效

  • 18
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张呱呱_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值