基础IO(软硬链接和动静态库)

一、软硬链接内容与特点

1、创建软硬链接

软链接:ln -s 目标文件 软链接名

硬链接:ln 目标文件 硬链接名

2、软硬链接内容

软链接:存放目标文件路径字符串,类似windows中的快捷方式。

硬链接:存放目标文件名和inode映射关系。

3、软硬链接特点

上图中我们发现创建的软链接是独立文件,与目标文件的inode不同。

硬链接不是独立文件,inode与目标文件相同。

在文件权限的右边数字是硬链接数,是文件磁盘级引用计数(有多少文件名字符串通过inode_number 指向 inode)

4、软硬链接作用

(1)软链接:快速找到对应文件

(2)硬链接:构建Linux路径,可以让我们用 .  ..  来进行路径定位。一般用来做文件备份。

注意:Linux不允许给目录建立硬链接,防止路径环绕。但由于 .  ..  是固定名称,指令都认识,所以防止了路径环绕,也就能给目录建立硬链接。

5、总结

定位一个文件有两种方式

(1)通过路径(软链接)

(2)找到inode_number(硬链接)

用来找到inode,最后找到文件。

6、目录的引用计数

上图是目录结构,用Linux指令我们发现 dir 目录的引用计数是3,otherdir 目录引用计数是2。

一个目录创建时引用计数是2(自己和自己目录下的 . )

目录A内部创建一个目录,A目录引用计数+1(新目录下的 .. 指向A目录)

所以一个目录包含的目录个数是目录引用计数-2

二、文件写入和二进制写入

文件写入是语言层概念,是通过函数 fprintf() printf() 等调用系统调用的方法向文件中写入一些字符

二进制写入是把数据转化成二进制写入,与字符写入有本质区别。

int a = 0; scanf("%d", a);

我们从键盘中输入字符(文件写入),函数通过ASCII表转换成二进制写入。

三、动静态库

1、库

所谓的库就是把实现函数的 .c 文件编译成 .o 文件打包,头文件是手册提供函数声明,.o 文件提供函数实现,我们写一个 main.c 文件调用方法与.o 文件链接。

2、静态库的生成与使用

(1)生成静态库

sr -rc libmyc.a *.o

ar:相当于打包

-r:文件存在就替换

-c:文件不存在就创建

libmyc.a:库名,开头是lib,结尾是 .a

*.o:编译好的所有 .o 文件

(2)使用静态库

若已经把库安装到系统目录下

gcc main.c -l myc

-l:gcc只认识默认安装的c库,自己的库要带 -l

myc:库名要去掉 lib 和 .a

若未安装到系统目录

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

-I:大写i,指定用户自定义头文件路径

-L:指定用户自定义库文件路径

-l:小写l ,确定第三方库名

3、动态库的生成与使用

(1)生成动态库

编译.o文件

gcc -fPIC -c *.c

-fPIC:产生位置无关码

打包形成动态库

gcc -shared *.o libmyc.so

-shared:生成共享库格式

(2)使用动态库

不仅要在gcc编译main.c时指明头文件路径,库路径,库名,还要告诉操作系统动态库的位置。

方法如下

a、把动态库拷贝到 /lib64 目录(里面放有c标准库)

b、建立动态库软链接(最推荐)

c、环境变量 LD_LIBRARY_PATH 添加库路径

d、修改 .bashrc 中环境变量就能永久生效

e、/etc/ld.so.conf.d 新增配置文件 xxx.conf,里面加库路径,最后 ldconfig

四、动态库加载

一个动态库 支只加载一份共享库在内存,通过页表映射到进程地址空间。

我们的可执行程序,编译成功但没加载运行时,二进制代码中就已经存在地址。

我们编译形成ELF可执行程序,编译的二进制文件有自己的固定格式,ELF有可执行程序头部和属性。

可执行程序编译后会形成许多汇编语句,每条汇编语句都有地址,编址范围 000....000~FFF...FFF

是绝对编址,也叫做平坦模式。

ELF绝对编址(头部信息)+ 加载器就能知道虚拟地址空间中各个区域的起始地址和终止地址,还有main()函数入口地址。

mm_struct 作为一个结构体,里面分配空间的字段在一开始并不知道要分配多少空间,只有可执行程序自己知道,所以一开始初始值从程序头部信息来。

所以虚拟地址空间是由OS,加载器,编译器共同支持。

所以程序加载到物理内存时分配了物理地址,加上一开始程序自带的虚拟地址就可以填页表。

CPU中pc指针记录代码运行下一条语句的虚拟地址(一开始是main)

虚拟地址->物理地址->读指令

总结

(1)进程创建阶段,初始化地址空间,CPU知道main函数地址。

(2)加载到内存之后,每一行代码有了物理地址,与虚拟地址构成页表。

库函数的调用

库中记录函数相对于库地址的偏移量,当正文部分识别调用库函数时就是找到对应库地址,再加上偏移量就能找到函数。

静态库是直接拷贝到程序正文部分直接调用

所以-fPIC选项就是把库加载到任意位置内存,和可执行程序无关。

  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值