【Linux】--动态库与静态库的生成与使用

动态库与静态库的生成与使用

首先我们还是先理解下为什么要用库?举个栗子,当我们要把自己的代码给别人用的时候,又不想给人家源码,所以就将自己的代码封装成库,那么别人就只能通过库来使用你的方法,但是看不到你的源码。

1、概念

动态库:即为动态链接库。以.so为文件后缀名。在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入,因此程序在运行时候还需要动态库存在。
静态库:以.a为后缀名,将库中的代码生成到可执行程序里面,运行时无需依赖库的存在。当程序运行的较多会形成代码冗余。
库文件:把一大堆代码的实现打包成一个文件,库中的代码不能有main函数

2、动态库的生成

使用工具:gcc
gcc -fPIC -c child.c -o child.o
gcc --share child.o -o child
演示:
首先得生成三个文件分别是child.c child.h和main.c
现在要将它打包成动态库,在命令行输入以下命令:

在这里插入图片描述
第一行是进行编译,将.c文件转化成.o目标文件。
第二行的share的意思是生成一个动态库,-fpic是产生位置无关代码,因为动态库的代码动态运行时才加载,这个动态库是要被映射到程序的各个自己的独立的虚拟地址空间的,无法保证每个程序将他的动态库加载到同一个位置,因此-fpic 便于映射到每一个地址.
libchild.so的意思:lib是前缀,child是自己给自己的动态库起的名字,.so是生成的动态库的后缀。

3、静态库的生成

使用工具:gcc/ar
命令:
gcc -c child.c -o child.o //生成目标文件
ar -cr libchild.a child.o…
在这里插入图片描述
直接使用上述代码,在命令行输入ar -cr libchild.a child.o,会发现生成两个文件libchild.a和libchild.so,这就生成了静态库。libchild中lib是前缀,child是我们给静态库起的名字

4、如何使用?

使用的话就是将库和我们的.o文件放到一块,生成一个可执行程序。
库的使用,分为两种情况
链接的时候使用库(有三种方式):
当我们写入命令:gcc -o main main.o -lchild 表明我们链接的是child这个库,会发现报错:cannot find -lchild
那么我们会有疑问,库明明就在那呀,为啥找不到呢?因为库的查找也有一个默认路径,但这个默认路径并不包含当前路径,根目录下面有很多的动态库和静态库,所以就有了第一种方法,我们就要将库的链接放到指定路径下:
(1) 将库文件放到指定路径下在这里插入图片描述
第一行是说将生成的库拷贝到根目录lib64里面去,当重新执行第二行命令编译时发现编译成功。但是一般情况下我们并不会将库放到指定路径下,会污染系统根目录,所以便有了第二种方式,放到我们自己指定的目录下。
(2) 设置LIBRARY_PATH环境变量
如下图,先删除掉我们刚才在lib64的库,重新编译发现编译错误(是为了防止上一次方法的干扰)
在这里插入图片描述
这时候我们便可以设置自己的环境变量
在这里插入图片描述
./是当前目录,如果环境变量直接等于当前目录的话,会把之前的值覆盖,所以我们加上$LIBRARY_PATH,再次编译发现也可以成功。
(3)通过gcc -L选项设置链接库的默认搜索路径
命令为:gcc -o main main.o -L ./-lchild 此种方法是最常用的
以下是第三种方式:其中-lchild是指定的链接库的名称,-l是指定库的名称 child使我们自己给库起的名字,-L是指定库的搜索路径 ./是当前目录
在这里插入图片描述
执行命令后发现指令编译成功

当我们使用指令./main的时候运行库,发现报错,那么就要用到以下方法来解决
运行的时候使用库:只有动态库才会在运行的时候加载库,有以下两种方法
(1)将库文件放置到指定路径下
(2)设置LD_LIBRARY_PATH环境变量
这里演示的是第二种,再次编译main.c文件发现编译成功
这里演示的是第二种
以上就是动态库和静态库的生成与使用。
今天先分享到这里,请继续关注笔者后续,进程间通信~

发布了33 篇原创文章 · 获赞 13 · 访问量 1066

猜你喜欢

转载自blog.csdn.net/Vicky_Cr/article/details/103093210