头文件和库文件-静态库和动态库
一、头文件和库文件
头文件提供声明,库文件提供定义/实现。
C代码的编译过程: 预处理(需要头文件) -> 编译 -> 汇编 -> 链接(需要库文件); 执行时可能还有动态链接过程。
编译的时候,只要有头文件中的声明就足够了。在链接的时候,把已经编译好的.obj和现有的.lib文件进行链接,这时就可以最终生成可执行文件了。其实头文件与其实现文件或相应lib文件都没有直接的联系。头文件是告诉编译器函数是如何去调用如何返回的,所有实现都是分别编译,最后在链接阶段链在一起。
头文件包含声明, 库文件包含实现或者与DLL库的连接
所以,如果在代码里要用到这些函数那么就要包含头文件,编译的时候才能知道这些函数的原形;
在进行代码连接的时候就需要库文件了,这时连接器就把函数的实现代码(静态库)连接到你的程序或者将你的函数调用连接到相应的DLL的对应函数(动态库)
lib是静态库, 编译的时候代码直接插入到你的程序 ,DLL是动态库,编译的时候,只是产生一些调用DLL内代码的导入表,真正运行的时候是调用的DLL内的代码。
总结起来就是,库文件通过头文件向外导出接口。用户通过头文件找到库文件中函数实现的代码从而把这段代码链接到用户程序中去。
.a代表传统的静态函数库(也称作归档文件:archive)
.so代表共享函数库
二、创建静态库文件:
1.创建源文件willku1.c和willku2.c
2.编译源文件生成.o文件(将要包含在库文件中的目标文件)
gcc -c willku1.c willku2.c =>willku1.o willku2.o
3.创建头文件ishead.h
内容:void willku1(char *);
void willku2(int);
4.创建应用程序app.c(将调用willku2.c文件)
#include "ishead.h"
5.编译、测试应用程序app.c
gcc -c app.c
gcc -o app app.o willku2.o
./app
6.创建并使用库文件(.a),使用ar创建归档文件并将目标文件加进去。
ar归档文件:将若干单独文件归并到一个大文件中,以创建归档文件或集合。
ar crv libwill.a willku1.o willku2.o
(ranlib libwill.a)
7.app.c使用函数库libwill.a
gcc -o app app.o libwill.a #gcc -o app app.o -L. -lwill
./app
三、动态库的生成及使用
静态库有很多缺点,所以有必要使用动态库。
1. 动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序。动态链接库是目标文件的集合,目标文件在动态链接库中的组织方式是按照特殊方式形成的。库中函数和变量的地址是相对地址,不是绝对地址,其真实地址在调用动态库的程序加载时形成。
2. 动态链接库的名称有别名(soname), 真名(realname)和链接名(linker name)。别名由一个前缀lib,然后是库的名字,再加上一个后缀“.so”构成。真名是动态链接库真实名称,一般总是在别名的基础加上一个小版本号,发布版本等构成。除此之外,还有一个链接名,即程序链接时使用的库的名字。
3.在动态链接库安装的时候,总是复制文件到某个目录下,然后用一个软连接生成别名,在库文件进行更新的时候,仅仅更新软链接即可。
生成和使用动态库:
1.看一个实例来了解如何自己生成静态库和使用静态库
创建程序文件
1>在test文件夹下有三个文件: main.c ,add.c,sub.c,tiger.h
2> main.c文件中的内容:
3>.tiger.h文件中的内容:
4>.add.c文件中的内容
5>.sub.c文件中的内容
动态库的生成
1>首先生成目标文件,但是此时要加编译器选项-fpic和链接器选项-shared,
gcc -fpic -c add.c
gcc -fpic -c sub.c
生成中间文件add.o和sub.o
2>其次生成动态库
gcc -shared –o libtiger.so add.o sub.o
生成动态库libtiger.so,libtiger.so就是我们生成的目标动态库。我们以后使用动态库和main.c程序生成可执行程序
以上两部也可以合成一步搞定:
gcc -fpic -shared add.c sub.c -o libtiger.so
2.使用动态链接库
在编译程序时,使用动态链接库和静态库是一致的,使用”-l库名”的方式,在生成可执行文件的时候会链接库文件。
1>使用命令:
gcc -o main main.c -L ./ -ltiger
2>-L指定动态链接库的路劲,-ldtiger链接库函数tiger。-ltiger是动态库的调用规则。Linux系统下的动态库命名方式是lib*.so,而在链接时表示位-l*,*是自己命名的库名。
3>但是程序会提示如下错误
error while loading shared libraries: libtiger.so: cannot open shared object file: No such file or direct
这是因为程序运行时没有找到动态链接库造成的。程序编译时链接动态库和运行时使用动态链接库的概念是不同的,在运行时,程序链接的动态链接库需要在系统目录下才行。
4>使用以下方法可以解决此问题
a. 在linux下最方便的解决方案是拷贝libtiger.so到绝对目录 /lib 下(但是,要是超级用户才可以,因此要使用sudo哦,亲)。就可以生成可执行程序了
b.第二种方法是:将动态链接库的目录放到程序搜索路径中,可以将库的路径加到环境变量LD_LIBRARY_PATH中实现:
export LD_LIBRARY_PATH='pwd':$LD_LIBRARY_PATH
执行此命令后也可以生成可执行程序