库:
库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。
如何使用
用户需要同时具有头文件和库。
头文件(相当于说明书的作用,能够知道这个库能干嘛)
制作出来的库(具体的实现,存放.c、.cpp)
静态库:
是在程序执行前(编译)就加入到目标程序中去了。
优点:
1、静态库被打包到应用程序中运行速度快
2、发布程序无需提供静态库,因为已在app中,移植方便
缺点:
1、链接时完整的拷贝至可执行文件中,被多次使用就有多份冗余的拷贝。
2、更新、部署、发布、比较麻烦。
动态库:
是在执行程序时动态(临时)由目标程序去调用
优点:
1、链接时不复制,程序运行时由系统动态加载到内存,供程序使用,系统只加载一次,多个程序可以共用,节省内存。
2、程序升级简单,因为app里面没有源代码,升级之后只要库的名字不变,函数名以及参数不变,只是实现了优化,就能加载成功。
缺点:
1、加载速度比静态库慢
2、发布程序需要提供依赖的动态库
静态库的制作和使用
(1)命名规则
静态库文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名。
(2)制作步骤
原材料:源代码.c 或者 .cpp
1、将.c文件生成.o,gcc a.c b.c -c
pi@raspberrypi:~/test$ ls
togetherfunc1.c togetherfunc1.h togetherfunc.c
pi@raspberrypi:~/test$ gcc togetherfunc1.c -c
pi@raspberrypi:~/test$ ls
togetherfunc1.c togetherfunc1.h togetherfunc1.o togetherfunc.c
2、将.o 打包
ar rcs 静态库的名字 原材料
ar rcs libtest.a a.o b.o
pi@raspberrypi:~/test$ ar
//输入指令ar,查看各个参数的功能
ps:以下是一些指令的介绍
mv togetherfunc1.c ~
//~表示工作目录 将这个.c文件移到工作目录
cp ~/togetherfunc1.c .
//从工作目录再移到当前文件
mv togetherfunc1.* ~
//将当前文件夹下的以togetherfunc1开头的文件移动到工作目录下。 * 是通配符
代码演示
pi@raspberrypi:~/test$ ls
togetherfunc1.c togetherfunc1.h togetherfunc1.o togetherfunc.c
pi@raspberrypi:~/test$ ar rcs libfunc1.a togetherfunc1.o
pi@raspberrypi:~/test$ ls
libfunc1.a togetherfunc1.c togetherfunc1.h togetherfunc1.o togetherfunc.c
(3)库的使用
若直接-l 编译会报错,因为-l 会优先从/urs/lib 或 /urs/local/lib 中去找,但我们想让它优先从当前路径去找,就要用到-L。
pi@raspberrypi:~/test$ gcc togetherfunc.c -lfunc1
/usr/bin/ld: cannot find -lfunc1
collect2: error: ld returned 1 exit status
应该这样使用:
gcc togetherfunc.c -lfunc1 -L ./ -o mainProstatic
//-l 是指定要用的动态库名称,库名砍头去尾去掉lib和.a
//-L 告诉gcc编译器从-L指定的路径去找静态库。默认先是从/urs/lib 或 /urs/local/lib 中去找,若-L后先从指定的路径去找,找不到再从/urs/lib 或 /urs/local/lib 中去找。
// ./表示当前路径
// -o后是编译后程序的名字
动态库的生成和使用
(1)命名规则
动态库的命名方式与静态库类似,前缀相同,为“lib”,后缀变为“.so”。所以为“libmytime.so”
(2)制作步骤
输入指令:
gcc -shared a.o b.o -o libxxx.so
代码演示:
pi@raspberrypi:~/test $ ls
libfunc1.a togetherfunc1.c togetherfunc1.h
pi@raspberrypi:~/test $ gcc -shared -fpic togetherfunc1.c -o libfun1.so
pi@raspberrypi:~/test $ ls
libfun1.so libfunc1.a togetherfunc1.c togetherfunc1.h
//-shared 的意思是指定生成动态库
// -fpic 标准,fpic选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。
(3)动态库的使用
动态库优先从当前路径去找,没找到的话再去/usr/lib/下去找
sudo cp libfun2.so /usr/lib/
//将生成的动态库拷贝到/usr/lib
sudo rm /usr/lib/libfun2.so
//从/usr/lib/中移除刚才移入的动态库
gcc togetherfunc.c -l fun2 -L ./ -o mianPrody
//这是编译的时候
//运行的时候可能此时会提示No such file or directory,需要进行环境变量的设置
动态库无法加载(引用动态库,怎么指定动态库的位置):
临时设置:
在终端进行:
export LD_LIBRARY_PATH=“动态库的路径”
利用脚本:
vi start.sh
//创建一个.sh文件
export LD_LIBRARY_PATH="/home/pi/test//动态库的路径"
./mianPrody//所要执行的程序名称
//在文件夹中输入以上内容
chmod +x start.sh
//给脚本加可执行的的权限
./start.sh
//执行该脚本
计算文件大小
pi@raspberrypi:~/test $ du libfunc1.a
4 libfunc1.a
pi@raspberrypi:~/test $ du mianPrody
12 mianPrody