一、静态库
1、静态库的命名
静态库的命名方式是“libxxx.a”,其中“xxx”为库名,库名前加“lib”,后缀用“.a”。
2、工作过程
在编译过程中,静态库的所有数据都被载进目标文件里。程序运行的时候就不再需要静态库了。
3、优点
编译后的执行程序不需要外部函数库支持。
4、缺点
(1)静态函数库编译成的文件占用的内存比较大。
(2)当静态库改变时,程序必须重新编译。
5、静态库的生成与使用
5.1 命令介绍
静态库的生成和使用过程中需要用到ar命令。ar是Linux系统的一个备份压缩命令,用于创建、修改备存文件(archive),或从备存文件中提取成员文件。ar命令最常见的用法是将目标文件(.o文件)打包为静态链接库。ar命令带的参数不同,功能也不同,其参数如下。
(1)-c:创建一个库,不管这个库存不存在,都将创建。
(2)-r:在库中插入模块(替换)。若插入的模块在库中存在,则会进行替换。
(3)-s:创建目标文件索引,在创建较大的库时能加快时间。不管是否修改了库内容,都将更新符号表。
(4)-t:将库目录写到标准输出,如果指定文件名称,则显示指定的文件。如果不指定文件名称的话,则显示库目录的所有文件。
(5)-v:将建立新库的详细文件逐个写到标准输出。
【例】
注:由目标文件(.o)生成静态库文件。
5.2 静态库的使用
【例】
//add.c文件
#include "add.h"
int add(int a, int b)
{
return a+b;
}
//add.h文件
#ifndef __ADD_H__
#define __ADD_H__
#include<stdio.h>
#include<stdlib.h>
int add(int a, int b);
#endif
//sub.c文件
#include "sub.h"
int sub(int a, int b)
{
return a-b;
}
//sub.h文件
#ifndef __SUB_H__
#define __SUB_H__
#include<stdio.h>
#include<stdlib.h>
int sub(int a, int b);
#endif
//main.c文件
#include "add.h"
#include "sub.h"
int main()
{
int a = 10;
int b = 20;
printf("add(%d, %d)=%d\n", a, b, add(a,b));
a = 100;
b = 20;
printf("sub(%d, %d)=%d\n", a, b, sub(a,b));
}
运行静态库:
释:编译main.c文件时,将静态库mymath文件载入目标代码中,执行结果为10+20=30,100-20=80。其中,“-L”指定库路径,“.”指定当前目录,“-l”指定库名。
释:编译文件后,删除静态库,执行结果一样。
二、动态库
1、动态库的命名
这类库文件的命名规则是“libxxx.M.N.so”,其中“xxx”是库名,库名的前缀是“lib”(与静态库相同),“M”是库主版本号,“N”是库副版本号,“.so”是后缀。版本号可以省略,但是库名必须有。
2、工作过程
动态库不被载入代码中,当程序执行到相应函数时才调用。
3、优点
占用的内存小;当动态库改变时,程序不受影响。
4、缺点
执行时间比较长,因为当程序执行到某个函数时,才从外部调用动态库(相当于用时间换取空间)。
5、生成动态库
【例】
释:
(1)fPIC:表示产生位置无关码。
(2)shared:表示生产共享库格式。
注:动态库由目标文件生成。
6、运行动态库
【例】
释:编译“main.c”文件时链接到动态库“mymath”。使用“-lmymath”标记是为了告诉gcc驱动程序在链接时引用“mymath”动态库。如:
释:
(1)ldd可以查看可执行程序依赖的文件。
(2)拷贝共享文件(.so)到系统共享库路径下,一般指“/usr/lib”。
注:生成静态库,动态库文件的时候,可能会出现这样的错误:
“/usr/bin/ld: cannot find lc”。在root权限下,执行“yum install glibc-static”命令安装glibc-static即可。