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

news2024/11/20 6:14:39

一、软链接

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 指令让配置文件生效

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

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

相关文章

揭秘App全渠道统计服务:如何精准追踪你的用户来源?

在移动互联网时代&#xff0c;App的推广和运营至关重要&#xff0c;而渠道统计则是衡量推广效果的关键一环。近日&#xff0c;xinstall推出了一款全新的App全渠道统计服务&#xff0c;该服务旨在帮助开发者和运营者更全面地了解用户来源&#xff0c;优化推广策略&#xff0c;从…

前端JS加密库CryptoJS的常用方法

CryptoJS是前端常用的一个加密库&#xff0c;如MD5、SHA256、AES等加密算法。 官方文档&#xff1a;https://www.npmjs.com/package/crypto-js 安装方法 方法一&#xff1a;直接在html文件中引入 <script type"text/javascript" src"path-to/bower_componen…

C# 项目:导线计算 / 坐标转换 / 曲线放样 / 水准网 / 导线网平差

文章目录 Part.I IntroductionPart.II 软件简介Chap.I 导线计算Chap.II 坐标转换Chap.III 曲线放样Chap.IV 水准网 / 导线网平差 Part.III 软件使用过程中可能遇到的问题Reference Part.I Introduction 本文将对几个基于 C# 开发的软件进行简要的介绍&#xff0c;这些软件都是…

前端更优雅的使用 jsonp

前端更优雅的使用 jsonp 背景&#xff1a;最近项目中又使用到了 jsonp 这一项跨域的技术&#xff0c;&#xff08;主要还是受同源策略影响&#xff09;&#xff0c;下面有为大家提供封装好的函数及对应使用示例&#xff0c;欢迎大家阅读理解 文章目录 前端更优雅的使用 jsonp同…

SAP-ERP TM运输管理模块详解-1

简介 SAP中的运输功能(即TM模块,属于SD的子模块)是后勤执行的一部分,用于自动计算交货成本。也就是说,SAP可以让系统自动对销售发货的商品计算运费,对于运费占这个成本很大比重的销售模式,可以使用该功能。运输功能相对于SD其他模块,相对比较独立的,应用面不是很广。其…

【算法一则】【贪心】数组中的数可以拼装成的最大数

题目 给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 注意&#xff1a;输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 示例 1&#xff1a; 输入&#xff1a;nums [10,2] …

使用 frp 通过云厂商公网IP实现内网穿透

写在前面 有小伙伴推荐&#xff0c;简单了解博文内容涉及 内网穿透 工具 frp 的安装以及2个Demo内网的静态文件服务访问 Demo内网多端口映射 Demo理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的…

【数据分析面试】32.矩阵元素求和 (Python: for…in…语句)

题目&#xff1a;矩阵元素求和 &#xff08;Python) 假设给定一个整数矩阵。你的任务是编写一个函数&#xff0c;返回矩阵中所有元素的和。 示例 1&#xff1a; 输入&#xff1a; matrix [[1, 2, 3], [4, 5, 6], [7, 8, 9]]输出&#xff1a; matrix_sum(matrix) -> 45…

判断n以内的素数个数的五种方法+时间对比

目录 方法一&#xff1a;暴力法 复杂度 方法二&#xff1a;跨度为6的倍数的优化 复杂度 方法三&#xff1a;埃氏筛法 复杂度 方法四&#xff1a;埃氏筛法的改良 复杂度 方法五&#xff1a;线性筛 复杂度 性能对比测试 练习 方法一&#xff1a;暴力法 就是写一个函…

STL--string详解

STL基本内容 string是什么 string实质上是一个对象 string可看作一个串&#xff0c;类似字符数组 可以扩容&#xff0c;可以增删查改 可用下表访问操作符[]引用&#xff0c;修改某值 构造函数 默认构造 拷贝构造&#xff1a;参数为(string 或 char*) 求string对象的长度不…

锂电池SOH预测 | 基于SVM的锂电池SOH预测(附matlab完整源码)

锂电池SOH预测 锂电池SOH预测完整代码锂电池SOH预测 锂电池的SOH(状态健康度)预测是一项重要的任务,它可以帮助确定电池的健康状况和剩余寿命,从而优化电池的使用和维护策略。 SOH预测可以通过多种方法实现,其中一些常用的方法包括: 容量衰减法:通过监测电池的容量衰减…

C语言学习/复习36

一、程序的环境与预处理 二、翻译环境与执行环境 三、运行环境 四、预编译(预处理)详解

【Hadoop】-Apache Hive使用语法与概念原理[15]

一、数据库操作 创建数据库 create database if not exists myhive; 使用数据库 use myhive; 查看数据库详细信息 desc database myhive; 数据库本质上就是在HDFS之上的文件夹。 默认数据库的存放路径是HDFS的&#xff1a;/user/hive/warehouse内 创建数据库并指定hdfs…

SVN--基本原理与使用(超详细)

目录 一、SVN概述二、SVN服务端软件安装三、SVN服务端配置四、SVN客户端软件安装与使用五、SVN三大指令六、SVN图标集与忽略功能6.1 图标集6.2 忽略功能 七、SVN版本回退八、SVN版本冲突九、SVN配置多仓库与权限控制9.1 配置多仓库9.2 权限控制 十、服务配置与管理十一、模拟真…

JAVASCRIPT+PHP+GB2312字库文件实现浏览器LED滚动效果

一、效果 二、源码 1、test_led.html <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>MATRIX LED</title> <script src"https://cdn.staticfile.net/jquery/1.10.2/jquery.min.js"></script…

渗透攻击思考题

目录 问题一&#xff1a; 存储过程&#xff1a; 密文存储&#xff1a; 问题二&#xff1a; 问题三&#xff1a; 问题四&#xff1a; LM Hash的加密: NTLM Hash 的加密&#xff1a; 问题一&#xff1a; windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0…

数据聚类:Mean-Shift和EM算法

目录 1. 高斯混合分布2. Mean-Shift算法3. EM算法4. 数据聚类5. 源码地址 1. 高斯混合分布 在高斯混合分布中&#xff0c;我们假设数据是由多个高斯分布组合而成的。每个高斯分布被称为一个“成分”&#xff08;component&#xff09;&#xff0c;这些成分通过加权和的方式来构…

mysql-connector-java和spring-boot-starter-jdbc和mybatis-spring-boot-start

mysql-connector-java和spring-boot-starter-jdbc和mybatis-spring-boot-start JDBC是什么意思&#xff1f; JDBC是使用java语言操作mysql数据库的规范&#xff0c;java语言必须按照这个规范写才可以操作mysql数据库。 mysql-connector-java 在最开始的时候 程序中是不允许…

深入解析AI绘画算法:从GANs到VAEs

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

蛋糕购物商城

蛋糕购物商城 运行前附加数据库.mdf&#xff08;或使用sql生成数据库&#xff09; 登陆账号&#xff1a;admin 密码&#xff1a;123456 修改专辑价格时去掉&#xffe5;以及上传专辑图片 c#_asp.net 蛋糕购物商城 网上商城 三层架构 在线购物网站&#xff0c;电子商务系统 …