赞
踩
- 静态库是指后缀为.a的库文件,windows下为.lib
- 动态库是指后缀为.so的库文件,windows下为.dll
当一个文件要使用静态库的时候,它需要将它想使用的静态库的部分内容拷贝进自己的文件,然后再执行自己的程序。
当一个文件要使用动态库的时候,当它执行到库函数时,会跳转到动态库中,找到该函数的.o文件,去链接标准库中库函数的.o文件,最后再跳转回来。
正是因为两种库的差距,所以一般使用动态库的文件占用空间会比静态库小。
如果我们想自己写一个静态库,该怎么做?
我们知道,对于任何一个库,都至少包含了一个头文件。这个头文件的作用是提供库的使用方法(相当于使用说明书)。而真实的库文件,是二进制代码,库的作者可以选择不公开,只提供使用,不让库的使用者看到具体的代码。
如果我们要创建一个静态库,首先需要一个头文件。
下一步是要写对应的方法。
此时,我们已经具备制作一个库的全部条件了(准备好配菜了),接下来就是进行具体的制作(进厨房加工)。
想要将一个文件变成可执行程序,需要做的是:预处理,编译,汇编,链接。
而这里,我们首先需要将源文件打包成一个二进制文件,也就是.o文件。
我们执行红色框中的指令,最后可以得到黄色框中的.o文件。
注意白色框,可以看到,我们所做的一切都是在mylib目录下的。我们在这个目录下制作了一个库。
此时我创建了一个classmate的目录,目的是模拟别人使用库的情况。
此时可以看到这个classmate目录里什么都没有。
此时,我们把别人目录下的.o和.h文件都拿过来了。相当于把我需要的都拿过来了。
.h用于告诉我库的使用方法。
.o是库的具体实现方案。
这一步就是编写程序,并且使用别人的库
如果我今天写了很多个静态库文件,该如何打包?
- 指令 ar -rc libname.a 待打包的库文件.o
- 作用:将所有待打包的库文件制作成静态库
上面这一系列操作表示我写了两个头文件和源文件,并且,将这两个文件都制作成.o文件了。
接下来,我将使用ar指令将这些.o文件打包制作成一个静态库。
接下来将我们的静态库打包给别人用,可以使用makefile一步到位
这一步的意义是:
效果:
- tar指令:tar czf 打包文件.tgz 被打包的文件
- 作用:用于打包压缩
- czf表示:c--打包, z--压缩, f--指定打包后的文件名
这里的将myliba.tgz从其他地方拿过来和解压缩,就像是从网上下载库一样。
写好test.c文件,准备使用库
make的时候报错,说找不到头文件。
明明已经弄好库了,怎么可能找不到呢? --就在下面,myliba里面
这种方法类似于我们安装软件,使用gcc的时候,它会自动去系统默认路径下搜索所需要的头文件和库文件,也就是C语言标准库所在的路径。
- 头文件默认搜索路径:/usr/include;
- 库文件默认搜索路径:/usr/lib64;
因此,我们只需要将头文件和库文件安装到系统默认的路径下就行了。
到usr/include目录下就可以看到我们的.h文件了
同时,在usr/lib64目录下也能看到我们的静态库了
接下来直接像使用以前的静态库一样使用我们的静态库就行了。
直接make之后报错说找不到Add。这是因为,gcc不知道要链接默认路径库里的哪个库(找不到使用接口的定义 -- 代表是库出问题了)。
我们需要告诉编译器使用的库的名字是什么就行了。
指令:gcc -o test test.c -lmylib
mylib是libmylib.a掐头去尾的结果,也是库真实的名字。
涉及一个问题:为什么我们使用stdio这样的库的时候,gcc时就不需要加上-l呢?
---- 因为那不是第三方库,是官方提供的库,系统能够默认认识,所以不需要特别指明。
但是,我们所写的第三方库并没有经过验证,如果直接放到系统的默认路径下,很可能导致污染系统的其他库和头文件。所以,我们可以采用第二种方式:
自己指定
也可以将上述指令写入makefile,这样就不用每次都这么繁琐了。
拥有前面的基础,这里就直接使用makefile文件一键生成
这是目前所拥有的源文件和头文件,直接生成.o文件制作成动态库
使用指令之后得到如下结果:
接下来,打包动态库,将动态库压缩,就可以拿给别人用了。
此时我作为使用者,将别人的mylibso.tgz下载到我的目录下了。我该如何使用呢?
使用方法有四种。下面分别讲解
像静态库一样,直接将文件解压缩,安装到系统gcc执行的默认路径
头文件:usr/include
库文件:usr/lib64
这一步是将我们的文件和库文件进行链接。
可以看到,我们链接的步骤是正确的,并没有报错。
生成的文件是这样的:
接下来我们直接运行文件:
出现报错:显示找不到动态库
这里需要说明,为什么静态库进行到上一步可以直接运行,而动态库却不行?显示找不到动态库?
因为如果使用静态库,是将内容直接拷贝到文件中
如果使用动态库,是将内容链接到文件中
所以我们之前所做的 gcc -o test test.c -I ……是在告诉gcc编译器,我们需要链接哪个文件,但是,编译完成之后就和gcc没有关系了。真正运行程序的时候就是要操作系统去动态库中找我们用到的内容。
但是,我们并没有告诉操作系统,我们的动态库在哪里,所以找不到。
告诉操作系统动态库在哪里:
在执行程序的时候,操作系统会从环境变量LD_LIBRARY_PATH中读取动态库的路径。
所以,我们只需要将动态库的路径放入到LD_LIBRAY_PATH中就行了。
/etc/ld.so.conf.d/路径下有很多的配置文件
创建一个文件,文件名随意,但是后缀必须是conf。
最后将动态库的路径放到这个.conf文件中
sudo ldconfig -- 更新配置文件
系统中装库的路径是usr/lib64
所以我们只需要将我们的动态库软链接到usr/lib64中,就可以直接使用了。
用ldd也可以看到test配置了动态链接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。