一、分文件编程
优点:
- 分模块的编程思想
- 功能责任划分
- 方便调试
- 主程序简洁
比如设计一个简单的程序来体现
主程序
函数功能
函数声明
运行
这只是一个简单例子实现,当代码工程量大,功能复杂时,分文件就必不可少。
二、库
简介
简单的说库就是模块,用于提供不同功能的模块。库从本质上来说是一种可执行代码的二级制形式,可以被载入到内存中使用,就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。在Linux系统中,库以文件的形式存在,并且可以分为动态链接库和静态链接库,简称静态库和动态库。其中,静态库文件的后缀为.a,动态库文件的后缀为.so。无论是动态库还是静态库,它们无非是向调用的人提供变量、函数或者类。
区别与优缺点
静态库:在程序编译的时候会被链接到目标代码中,目标程序运行的时候将不再需要该库
优点
- 静态库被打包到应用程序中,加载速度快
- 发布程序无需提供静态库,因为已经在app中,移植方便
缺点
- 因为与之相关的所有文件都会链接合成一个可执行文件,导致可执行文件的体积变大。浪费空间和资源
- 更新,部署,发布麻烦。
动态库:在程序编译的时候并不会被链接到目标代码中,而是在程序运行的时候才被载入
优点
- 链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序可以共用,节省内存。
- 程序升级简单,因为app里面没有库的源代码,升级之后只要库的名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功。
缺点
- 加载速度比静态库慢
- 发布程序需要提供依赖的动态库
Linux中命名系统中共享库的规则
三、静态库的制作和使用
这里就用上面分文件编程的代码文件做例子
制作格式:libxxxx.a (以“lib”开头,“.a”结束,中间的xxx为自定义的静态库名)
1、生成xxx.o文件
gcc xxx.c yyy.c -c 一次可以多个生成
2、生成libxxx.a文件
ar rcs libxxx.a xxx1.o xxx2.o (可以将一个或者多个.o文件打包)
ar //输入指令ar,查看各个参数的功能
//rcs就是指令ar的参数
mv add.c ~ //~表示工作目录 将这个.c文件移到工作目录
//~目录就是 /home/pi
cp ~/add.c . //从工作目录再移到当前文件
mv add. * ~ //将当前文件夹下的以add开头的文件移动到工作目录下。 * 是通配符
3、静态库的使用
gcc testMain.c -ltest -L./ -o maintest
-ltest :-l是制定要用的动态库,库名砍头去尾(比如我原先的库名是libtest.a,去掉lib和.a)
-L./ 告诉gcc编译器从-L指定的路径去找静态库。默认是从/usr/lib或 /usr/local/lib去找,不加会报错
四、动态库的制作和使用
格式:libxxx.so
gcc -shared -fpic xxx.c -o libXXX.so
-shared 指定生成动态库
-fpic表明使用地址无关代码。。在Linux系统下编译共享库时,必须加上这个参数,否则在链接的时候将会报错。因为共享库文件可能会被不同的进程加载到不同的位置上,如果共享对象中的指令使用了绝对地址、外部模块地址等,那么该库在被加载的时候,就需要修改地址,这样就不能实现多进程共享一份物理内存。
动态库的使用:
和静态库一样
gcc xxx.c -ltest -L./ -0 xxx
但是在编译时程序运行的时候去找自己编译的动态库,出现找不到的情况。
指定动态库的位置
方法一·
在配置文件 /etc/ld.so.conf中指定动态库搜索路径
sudo vim /etc/ld.so.conf
添加自己的动态库的路径
保存后执行 sudo ldconfig
方法二:
通过环境变量 LD_LIBRARY_PATH 指定动态库搜索路径
export LD_LIBRARY_PATH=“动态库的路径”
但是这样只是临时设置的,重新打开会话就无效,可以利用脚本执行
vi test.sh
添加可执行权限运行
du xxx 查看文件大小