我们在编写代码的时候,时常用到已有的接口,它们以库的形式提供给我们使用,常见形式有两种,一种常以.a为后缀(静态库);另一种以.so为后缀(动态库)。库就是指写好的、现有的,可以复用的代码。现实中不可能每个程序的代码都从零开始,都要依赖很多基础的底层库,因此库的存在意义是非同寻常的。
前提知识
1.windows下的静态库的后缀为.lib
2.windows下的动态库的后缀为.dll
3.程序编译成可执行程序的步骤:预处理、编译、汇编、链接
4.-L [path]:指定库路径
5.-l[库的名称(去掉前缀和后缀)]:指定库名(注意:没有空格)
6.ldd [可执行程序] :用来查看当前程序依赖的动态库文件的命令
静态库
(1)静态库的命名规则
静态库的命名由前缀(lib)、名称和后缀(.a)组成
(2)生成静态库
创建test.h和test.c文件(注意:不能写main)
test.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif // __ADD_H__
test.c
#include "add.h"
int add(int a, int b)
{
return a + b;
}
使用gcc -c add.c -o add.o 生成.o文件
生成静态库
查看静态库中的目录列表
(3)使用静态库
编写testMain.c
#include <stdio.h>
#include "add.h"
int main( void )
{
int a = 10;
int b = 20;
printf("%d\n", a, b, add(a, b));
}
指定静态库的路径与名称,编译
运行:(因为没有写生成可执行程序的名称,默认生成a.out)
动态库
(1)动态库的命名规则
静态库的命名由前缀(lib)、名称和后缀(.so)组成
(2)生成动态库
编写test.h和test.c
test.h
#ifndef _TEST_H_
#define _TEST_H_
void function();
#endif
test.c
#include "test.h"
#include <stdio.h>
void function()
{
printf("hello linux!\n");
}
生成动态库
(3)使用动态库
编写main.c
main.c
运行:
查看依赖的静态库:
区别
1.静态链接的可执行文件要比动态链接的可执行文件要大得多,因为它将需要用到的代码从二进制文件中“拷贝”了一份,而动态库仅仅是复制了一些重定位和符号表信息。
2.如果静态库中某个函数的实现变了,那么可执行文件必须重新编译,但对于动态链接,只需要更新动态库本身即可,不需要重新编译可执行文件。
3.静态链接的可执行文件不需要依赖其他的内容即可运行,而动态链接的可执行文件必须依赖动态库的存在。
4.相对来讲,动态库的处理要比静态库要复杂
5.由于静态库在链接时就和可执行文件在一块了,而动态库在加载或者运行时才链接,因此,对于同样的程序来说,静态链接的要比动态链接加载更快。