静态库:将多个目标文件打包一个文件 扩展名 .a
里面是.o可执行文件
1:gcc -c clc.c show.c //生成执行文件.o
2:ar -r libmath.a clc.o show.o//加载到静态库中
ar [选项] 静态库文件.a 目标文件列表.o
-r 将目标插入到静态库中,已存在更新
-q 将目标文件追加到静态库尾
-d 从静态库中删除目标文件
-t 列表显示静态库中的目标文件
-x 将静态库展开为目标文件
库文件名:libmath.a
3:gcc main.c -lmain -L.. -o main//编译文件
-l:库文件名(去掉lib和.o)
-L:库文件路径 通过环境变量设置路径LIBRARY_PATH=$LIBRARY_PATH:..
//计算模块头文件
#ifndef __CLC_H
#define __CLC_H
#include<stdio.h>
//加法函数
int add(int a,int b);
//减法函数
int sub(int a,int b);
#endif
//计算模块函数实现
#include"clc.h"
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
//显示模块头文件
#ifndef __SHOW_H
#define __SHOW_H
#include<stdio.h>
void show(int , char, int, int);
#endif
//显示模块函数实现
#include"show.h"
void show(int x, char op, int y, int res)
{
printf("%d %c %d = %d\n",x,op,y,res);
}
//接口文件
#ifndef __MATH_H
#define __MATH_H
#include"show.h"
#include"clc.h"
#endif
#include<stdio.h>
#include"math.h"
int main()
{
int a = 123;
int b = 456;
show(a,'+',b,add(a,b));
show(a,'-',b,sub(a,b));
return 0;
}
动态库:扩展名 .so s:share o:object
gcc -c -fpic clc.c
gcc -c -fpic show.c
gcc -shared clc.o show.o -o libmath.so
gcc main.c libmath.so
./math
配置环境变量:LD_LIBRARY_PATH
PIC:位置无关码
动态库与静态库优缺点:
静态库:体积大,执行速度快,不依赖库的存在,不易于维护
动态库:体积小,执行速度慢,依赖库的存在,易于维护
动态库的动态加载
什么时候用什么时候加载,避免内存浪费。
#include<stdio.h>
//使用动态加载库文件需要包含此头文件
#include<dlfcn.h>
int main()
{
//加载库libmath.so到内存 RTLD_LAZY:延时加载 RTLD_NOW:立即加载
void *handel = dlopen("/home/tarena/UC/day02/shared/libmath.so",RTLD_NOW);
if(handel ==NULL)
{
fprintf(stderr,"dlopen%s\n",dlerror());//stderr代表标准错误,
//是一个文件,用fprintf输出到屏幕
return -1;
}
//获取库函数地址
int (*add)(int ,int) = dlsym(handel,"add");
if(add == NULL)
{
fprintf(stderr,"dlsym:%s\n",dlerror());
return -1;
}
int (*sub)(int ,int) = dlsym(handel,"sub");
if(sub == NULL)
{
fprintf(stderr,"sub:%s\n",dlerror());
return -1;
}
void (*show)(int,char,int,int) = dlsym(handel,"show");
if(show ==NULL)
{
fprintf(stderr,"show:%s\n",dlerror());
return -1;
}
//使用库
int a = 123;
int b = 456;
show(a,'+',b,add(a,b));
show(a,'-',b,sub(a,b));
//卸载库
if(dlclose(handel))
{
fprintf(stderr,"close:%s\n",dlerror());
}
return 0;
}
执行命令:gcc load.c -ldl
-ldl:-l代表库文件名 dl文件名
辅助工具:
查看符号表:nm(查看哪些是自己的函数,哪些是调用的函数等等、、、)
列出目标文件、可执行程序、静态库或共享库(动态库)中的符号
例如:nm libmath.a
查看依赖:ldd(查看文件需要哪些库)
查看可执行文件或者共享库多依赖的共享库
例如: ldd a.out