库有两种,一种是静态链接库,一种是动态链接库,不管是哪一种库,要使用它们,都要在程序中包含相应的include头文件。我们先来回顾一下程序编译的过程。如下图:
库:本质一个目标文件,这个文件的后缀有两种格式,对应两种库
静态库
.a (linux环境下)
.lib (Window环境下)动态库
.so (linux环境下)
.dll(windows环境下)静态库链接(.a):程序在链接的时候,将源文件中用到的库函数拷贝到内存与汇编生成的目标文件.o合并生成可执行文件。该可执行文件可能会比较大。
这种链接方式的好处是:方便程序移植,因为可执行程序与库函数再无关系,放在如何环境当中都可以执行。
缺点是:文件太大。多次拷贝库程序,不仅浪费空间,而且文件体积大
- 动态库链接(.so):程序在运行时才去链接动态库代码,多个程序共同使用这个代码,
只应用一个库,这个库在内存中只有一份,供所有程序使用。
优点:程序运行过程中动态调用库文件,很方便,又不占空间,
缺点:动态链接有一个缺点就是可移植性太差,如果两台电脑运行环境不同,动态库存放的位置不一样,很可能导致程序运行失败。
下面实现一个静态库文件()
add.h
#pragma once
int add( int a,int b);
sub.h
#pragma once
int sub( int a,int b);
add.c
#include "add.h"
int add( int a,int b)
{
return a+b;
}
sub.c
#include "sub.h"
int add( int a,int b)
{
return a-b;
}
main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main( )
{
int a=20;
int b=10;
printf( "add( a,b)=%d\n ",a,b,add( a,b));
printf( "sub( a,b)=%d\n ",a,b,sub( a,b));
return 0;
}
makefile文件
.PHONY:all
all:add.o sub.o
add.o:add.c
gcc -c add.c -o add.o
sub.o:sub.c
gcc -c sub.c -o sub.o
.PHONY:clean
clean:
rm -f *.o
编写好上述代码后按照以下做法即可实现一个静态库
第一步:生成目标文件
执行make,生成目标文件。由于静态库是在编译链接的时候把库的代码链接到可执行文件中去,生成 *.o
文件是便于链接。
第二步:生成静态库
这里静态库名前要以lib开头,以.a结束
[zyc@localhost lib]$ ar -rc libmymath.a add.o sub.o
ar: 是gnu的归档工具
-rc: replace and creat
第三步:查看静态库中的目录列表
[zyc@localhost lib]$ ar -tv libmymath.a
rw-rw-r-- 500/500 1240 Mar 30 00:49 2018 add.o
rw-rw-r-- 500/500 1240 Mar 30 00:49 2018 sub.o
- t : 列出静态库信息
- v 列出详细信息
第四步:测试目标文件
测试时去掉静态库名前缀lib和.a后缀
[zyc@localhost lib]$ gcc main.c -L. -lmymath
[zyc@localhost lib]$ ls
add.c add.h add.o a.out libmymath.a main.c makefile sub.c sub.h sub.o
[zyc@localhost lib]$ ./a.out
add( a,b)=20
sub( a,b)=20
- -L 指定库路径()
- -l 指定库名
测试目标文件生成后,即使删除静态库,程序依然可以执行。
[zyc@localhost lib]$ rm libmymath.a
[zyc@localhost lib]$ ls
add.c add.h add.o a.out main.c makefile sub.c sub.h sub.o
[zyc@localhost lib]$ ./a.out
add( a,b)=20
sub( a,b)=20
以上就是自己打造的静态库。
下面来看动态库的打造
由于动态库暂时运行不出来,先不放动态库程序了,后续更新