个人主页:点我进入主页
专栏分类:C语言初阶 C语言进阶 数据结构初阶 Linux C++初阶 算法 C++进阶
欢迎大家点赞,评论,收藏。
一起努力,一起奔赴大厂
目录
一.软硬链接
1.1如何软硬链接
1.2软硬链接的作用
1.2.1软链接(快捷方式)
1.2.2硬链接(备份)
1.2.3 mkdir计数为什么为2
二.动静态库
2.1基础储备
2.2静态库
2.2.1创建静态库
2.2.2静态库的安装删除和使用
2.3动态库
2.3.1动态库的创建
2.3.2动态库的使用
2.3.2.1动态库使用常遇到的问题
2.3.2.2解决动态库执行找不到库的问题
2.3.2.2.1安装到系统的库中
2.3.2.2.2环境变量
2.3.2.2.3修改配置文件
2.4动态库加载---可执行程序和地址空间
一.软硬链接
1.1如何软硬链接
软链接的建立的指令如下:
ln -s mystdio.c mystdio.link
输入
ll -i
硬链接的建立如下:
ln mystdio.c mystdio_hard.link
输入
ll -i
1.2软硬链接的作用
1.2.1软链接(快捷方式)
在上面可以看到
mystdio.c和mystdio.link的inode的号不同,这个软链接有什么用呢?软链是一个独立的文件。因为它有一个独立的inode number,软链接的内容是目标文件所对应的路径字符串,它类似于windows的快捷方式。
1.2.2硬链接(备份)
同样在硬链接中它的inode number和mystdio.c相同,所以它不是一个独立的文件,因为它没有独立的inode number,硬链接就是一个文件名和inode的映射关系,它还有一个2,这个就是表示用这个inode number,它相当于一个智能指针,它们指向同一块内存,当删除一个,这个2就变成1
它先当与,其实这个硬链接就相当于一个备份。
注意硬链接不能链接目录。当对目录进行硬链接可以看到
为什么呢?如果可以,当操作系统进行搜索到这个文件,所以它就会回到哪里,例如root.link是根目录进行硬链接,放在code目录中,当运行到这里就又会回到根目录就会造成回路。
1.2.3 mkdir计数为什么为2
创建一个test文件夹
为什么???test目录本身一个,它的inode number 266335,进入test
其中的.文件也是 266335,它也是指向本身,所以它的计数为2.
二.动静态库
2.1基础储备
在平时我们使用动静态库吗??使用果,而且经常使用,输入指令
ll /usr/lib64
可以看到内置的库,在一个可执行程序中,可以输入指令
ldd a.out
既可以看到a.out所用到的库
在Linux中动态库的后缀是.so,静态库的后缀是.a。对于动静态库我们需要知道它是他如何制作会让如何使用。
2.2静态库
2.2.1创建静态库
生成静态库的指令(其中.c不包括main函数)
gcc -c *.c
ar -rc libmyc.a *.o
其中-c会直接生成同名的.o文件,它就会生成一个libmyc.a,这就是我们的静态库,当别人想要时我们给他提供这个静态库和.h它自己写main函数就可使用了。
2.2.2静态库的安装删除和使用
下面是情景模拟: 当获取了.h和静态库后
写一个main函数
#include "mymath.h"
#include "mystdio.h"
int main()
{
printf("%d\n",Add(1,2));
return 0;
}
当我们想生成可执行程序时需要输入指令
gcc main.c libmyc.a
当然可以将这个库和.h进行安装,看安装过程:
sudo cp libmyc.o /usr/lib64
sudo cp *.h /usr/include
输入完成后就好了,当想使用gcc直接想生成可执行程序时发现
这是因为我们自己安装的属于第三方库,如果想要使用需要输入指令:
gcc main.c -lmyc
但是非常不建议这样做,因为我们自己写的尽量不要安装到lib64中,我们删除,可以使用下一种方法:
卸载指令:
sudo rm -rf /usr/lib64/libmyc.a /usr/include/mystdio.h /usr/include/mymath.h
可以创建一个mylib的文件夹,然后再往里面添加目录include和lib,将.h和.a分别放入其中,结果如图:
我们生成可执行程序输入指令
gcc main.c -I mylib/include -L mylib/lib -lmyc
为什么没有头文件的名称??其实在代码中就包含了头文件的名称。
2.3动态库
2.3.1动态库的创建
生成动态库需要输入指令:
gcc -fPIC -c*.c
gcc -shared *.o -o libmyc.so
就会生成:
2.3.2动态库的使用
2.3.2.1动态库使用常遇到的问题
将libmyc.so安装到mylib中
输入指令进行编译:
gcc main.c -I mylib/include -L mylib/lib -lmyc
运行后可以看到报错:
这是为什么?输入指令:
ldd a.out
libmyc.so是刚刚安装上的,,为什么会找不到?这是因为只是告诉了gcc/g++没有告诉操作系统只有编译阶段有,运行阶段没有,为什么静态库就不需要???事实上静态库在编译阶段就将库拷贝到可执行程序中了,这也是为什么静态库生成的可执行程序占用的内存大。既然库文件有静态库也有动态库,它们俩的指令一样,为什么会先用动态库呢???这就是动静态库的规则,默认情况下是先用动态库,没有动态库才会使用静态库。当假如-static选项时会使用静态库,看指令:
gcc main.c -I mylib/include -L mylib/lib -lmyc -static
查看此时使用的库
没有。
2.3.2.2解决动态库执行找不到库的问题
2.3.2.2.1安装到系统的库中
安装:
sudo cp mylib/include/*.h /usr/include
sudo cp mylib/lib/*.so /usr/lib
执行:
ldd a.out
2.3.2.2.2环境变量
在家目录中进入.bashrc进行修改
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yang/linux/code/roommate/mylib/lib
2.3.2.2.3修改配置文件
ls /etc/ld.so.conf.d
在里面加入
/home/yang/linux/code/roommate/mylib/lib
最后输入
idconfig
2.3.2.2.4软链接
ln -s /root/linux/code/roommate/mylib/lib/libmyc.so /lib64/libmyc.so
注意一定要完整的路径
2.4动态库加载---可执行程序和地址空间
在一个进程中动态库加载到内存后libmyc.so映射到页表,然后加载到进程地址空间的共享区,当调用时再到共享区call这个库。当有一个新的进程用到libmyc.so库时它不会在内存中再次加载这个库。
可执行程序加载到内存,就会有物理地址,也就会有虚拟地址,在cpu中有一个pc指针(pc指针能得到main函数的入口地址),页表映射找到可执行程序。
code.exe执行到myAdd,当执行到libmyc.so的函数时,到共享区查看有没有加载这个库(库有没有加载??先描述在组织),有的话就去寻这个函数地址(虚拟地址+地址偏移量),然后运行。。