1、概念
一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程序使用。程序函数库可以使整个程序更加模块化,更容易重新编译,而且更方便升级。
(加密)而且在实际编程中,有时并不希望使用者看到函数源代码,就要打包函数库,让使用者看不到源代码。
程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数库(dynamically loaded libraries):
1、静态函数库:是在程序执行前就加入到目标程序中去了 。
优点:1、静态库被打包到应用程序中,加载速度快
2、发布程序无需提供静态库,因为已经在app中,移植方便
缺点:1、链接时完成地拷贝到可执行文件中,被多次使用就有多份冗余拷贝,导致数据量大,耗内存;
2、更新部署麻烦,发布麻烦
2、动态函数库:同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll)
优点:1、链接时不复制,程序运行时动态加载到内存,供程序调用,系统只加载一次,多个程序共用,可以节省内存;
2、程序升级简单,因为APP中无库源码,升级后只要库的名字不变,函数名和参数不变,只是做了优化就拿加载成功。升级优化方便。
缺点:1、加载速度比静态库慢。
2、发布程序需要提供依赖的动态库。
2、库的制作及使用
准备工作:
1、先在主程序里包含自己编写的cal.h
include"cal.h"
补充:include<>与include" "的区别 1
cal.h的内容为:(函数的声明)
int add(int a,int b);
int minus(int a, int b);
要制作成库的cal1.C 文件
int add(int a,int b){
return a+b;
}
int minus(int a, int b){
return a-b;
}
静态库的制作
文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名。
静态库:格式xxxx.a
1. gcc cal1.c -c 生成xxx.o文件
生成了cal1.o文件
pi@raspberrypi:~/test $ gcc cal1.c -c
pi@raspberrypi:~/test $ ls
a.out cal1.c cal1.o cal.c cal.h libcal.c
2. xxx.o文件生成xxx.a静态库文件:ar rcs libcal.a cal1.o 2
生成libcal.a文件
pi@raspberrypi:~/test $ ar rcs libcal.a cal1.o
pi@raspberrypi:~/test $ ls
a.out cal1.c cal1.o cal.c cal.h libcal.a libcal.c libcalcufunc.a
静态库的使用
指令:
pi@raspberrypi:~/test $ gcc cal1.c -lcal1 -L ./ -o mainProStatic
pi@raspberrypi:~/test $ ./mainProStatic
请输入第一个数
1
请输入第二个数
2
加法:3
减法:-1
cal1.c:含有main函数的“主程序”C文件
-lcal1: -l是指定要用的库(链库),cal1为静态库名(砍头去尾)类似于-lpthread -lwiringPi;
-L:告诉gcc编译器从-L制定的路径去找静态库。默认是从/usr/lib /usr/local/lib去找
./:为当前路径
补充:-I(大写的i)表示:寻找头文件的目录
动态库
命名规则
格式:libxxx.so
动态库的制作:
动态库的创建可以一部到位的把功能 .c 文件编译成 .so 文件,使用下面指令:
生成libcalc.so文件
gcc -shared -fpic cal1.c -o libcalc.so
-shared:指定生成动态库
-fpic标准 :fPIC 选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。
编译:
动态库编译报错有报错
报错原因==:那是因为Linux系统在找动态库的时候,会在 /usr/lib/ 目录下找文件;从而找不到libcalc.so这个文件。
由于静态库的文件是事先编译好的加进去的所以不需要配置环境变量。而动态库是程序运行时动态加载的,所以需要寻找。
pi@raspberrypi:~/test $ gcc cal.c -lcalc -L ./ -o dynamic
pi@raspberrypi:~/test $ ./dynamic
./dynamic: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory
面对这种情况需要
通过环境变量LD_LIBRARY_PATH指定动态库搜索路径。
export LD_LIBRARY_PATH=/home/pi/test
但是这种方法只能用于这一个窗口,其他窗口就不行了。所以我们可以编写一个shell脚本来运行。
脚本内容
export LD_LIBRARY_PATH=/home/pi/test
./dynamic
//"dy.sh" [New] 2L, 49C written
创建完成后使用下面的命令给.sh文件加可执行的权限然后./dy.sh就可行执行了。
chmod +x dy.sh
一、引用的头文件bai不同
#include < >:引用的是编译bai器的类库路径里du面的头文件。
#include " ":引用的是你程序目录dao的相对路径中的头文件。
二、用法不同
#include < >:用来包含标准头文件(例如stdio.h或stdlib.h).
#include " " :用来包含非标准头文件。
三、调用文件的顺序不同
#include < > :编译程序会先到标准函数库中调用文件。
#include " " :编译程序会先从当前目录中调用文件。
四、预处理程序的指示不同
#include < >:指示预处理程序到预定义的缺省路径下寻找文件。
#include " " : 指示预处理程序先到当前目录下寻找文件,再到预定义的缺省路径下寻找文件。 ↩︎ar命令:可以用来创建、修改库,也可以从库中提出单个模块
参数r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
参数c:创建一个库。不管库是否存在,都将创建。
参数s:创建目标文件索引,这在创建较大的库时能加快时间。 ↩︎