库是什么:
1.通过Gcc编译器得到的
2.本质:
还是一个文件
这个文件里边就是程序员编写的代码
3.为什么要使用库
代码保密
为了部署和分发
100个源文件-》打包成一个库
4.如何使用库
要有动态库/静态库
来自于.c .cpp,里面是若干个函数的实现
需要有头文件声明源文件中实现的函数
有头文件
里面声明了可被调用 的函数名,和参数
静态库
- 命名规则
- Liunx
- libxxx.a lib->前缀,固定 xxx->库的名字,自己起 a - 后缀
- windows
- libxxx.lib
- 静态库的制作
源文件 ----- 预编译 ------ 编译 --------- 汇编 -------- 目标文件 .o ------ 使用ar工具编号压缩打包 ------静态库
静态库的制作
#ifndef _HEAD_H #define _HEAD_H int add (int a,int b); int subtract(int a,int b); int multiply(int a,int b); double divide(int a,int b); #endif
# ls
1.通过gcc得到 .o 文件 -c
add.c div.c head.h main.c mult.c sub.c
# gcc -c add.c div.c mult.c sub.c
add.c add.o div.c div.o head.h mian.c mult.c mult.o sub.c sub.o
2.将得到的o 打包-> 使用 ar工具 (archive)
ar rcs
-r :替换
-c :创建
-s :索引
ar rcs libcalc.a add.o div.o mult.o sub.o
静态库使用
静态库的分发
1.libcalc.a 2.头文件:head.h
静态库的使用
1.根据头文件中的api,编写测试程序
2.编译测试程序,指定静态库
.
目录 文件
|-----include head.h
|----lib main.c
|----src add.c div.c mult.c sub.c
#gcc -c src/*.c 直接编译找不到头文件
#gcc -c src/*.c -I ./include/ --------------- (-I)指定搜索的文件
gcc 指定静态库
gcc main.c -o app -I ./include/ -L -l 第一个是大i 第二个是小l
- L :静态库的路径
-l :静态库的名字:去掉lib ,去掉.a ,剩下的是名字 libcalc.a - >calc
$gcc main.c -o app -I ./include/ -L ./ -l cacl
动态库/共享库
共享-》共享内存中的库
命名规则
liunx : libxxxx.so 和静态库差不多
在liunx下是一个可执行文件
window : libxxx.dll 如果使用vs制作的 :libxxx.lib libxxx.dll
动态库的制作
源文件 ----- 预编译-E ----- 编译 -S ----- 汇编 -c ----目标文件 al.o ------ (-shared) ----- libxxx.dll
1.使用gcc 得到 .o
gcc sub.c add.c div.c mult.c -c -fpic
-fpic/-FPIC: 使用相对地址记录代码位置
2.使用gcc 得到动态库,以下两种格式都可以
gcc -shared add.o sub.o div.o mult.o -o libcalc.so
gcc -shared -o libcalc.so add.o sub.o div.o mult.o
动态库的使用
分发:头文件,动态库
使用:
编写测试文件,对头文件中声明的函数测试
app
include head.h
lib libcalc.a
libcalc.so
mian.c
src add.c div.c mult.c sub.c
$gcc main.c -o app -I ./include/ -L ./ -lcalc
只是保证在连接的时候没问题
解决动态库加载失败的问题
工作原理:
- 静态库 :gcc 进行连接之后,静态库中的代码和测试文件代码被打包到了可执行文件中
- 动态库:gcc进行连接之后,动态库不会和可执行程序打包在一起
- 程序启动之后,动态库会被动态加载到内存中
- 什么时候加载?程序需要调用add函数的时候,动态库被加载到内存
#可以通过命令检测是不是能加载到对应的库文件:
$ldd 可以执行程序的名字
ldd mian