引入:
分文件编程:
现有如下文件:
FileMain.c //主函数 C文件
FileFun.c //分函数 C文件
//主函数需调用分函数
创建一个 .h 文件:(内容为分函数的声明)
FileFun.h //内容为分函数的函数声明
然后在主函数C文件中加入头文件:
include "FileFun.h"
//双箭号是默认在 /usr/include/ 下寻找头文件,而双引号则是在当前路径寻找头文件
编译:
gcc FileMain.c FileFun.c
1、什么是库?
库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。
一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程序使用。程序函数库可以使整个程序更加模块化,更容易重新编译,而且更方便升级。
程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数库(dynamically loaded libraries)。
2、静态库:
是在程序执行前就加入到目标程序中去了
1 . 静态库被打包到程序中加载速度快
2 .发布程序无需提供静态库,因为已经在app中,移植方便
1 . 链接时完整的拷贝至可执行文件中,被多次使用就会有多次冗余拷贝
2 . 更新,部署,发布麻烦
静态库文件的格式:xxx.a
1.把 .c 或 .cpp 文件生成 .o 文件
gcc xxx1.c -c // xxx文件名
gcc xxx2.cpp -c // xxx文件名
xxx1.o // .o 文件(原材料1)
xxx2.o // .O 文件(原材料2)
2.把 .o 文件生成 .a 静态库文件(建议用 lib 开头)
ar rcs libtest.a xxx1.o xxx2.o
// 静态库名 原材料1 原材料2
gcc main.c -ltest -L ./ -o libtest
// main.c 主函数所在文件
// -ltest -l 是指定要用的静态库,静态库文件(libtest.a)去头去尾
// -L ./ -L 是指定 gcc 编译器寻找静态库的路径(-L ./ 指定为当前路径),否则默认在 /usr/lib 或 usr/local/lib 路径下寻找
!!此处也需要 .h(函数声明)文件,并在主函数所在文件包含相应头文件 !!
3、动态库:
动态函数库是在程序执行的时候动态(临时)由目标程序去调用
动态函数库和共享函数库是一个东西(在 linux 上叫共享对象库, 文件后缀是 .so ,windows 上叫动态加载函数库,文件后缀是 .dll )
Linux中命名系统中共享库的规则:
1.链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序可以共用,节省内存。
2.程序升级简单,因为app里面没有库的源代码,升级之后只要库的名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功。
1 . 加载速度比静态库慢
2 .发布程序需要提供依赖的动态库
动态库文件的格式:xxx.so
把 .c 文件生成 .so 动态库文件
gcc -shared -fpic libtest.c -o libtest.so
// -shared 指定生成动态库
// -fpic 作用于编译阶段,在生成目标文件时就得使用该选项(标准形式),以生成位置无关代码
// library.c 需生成为动态库的 .c 源文件
// library.so 生成的动态库的文件名
gcc main.c -ltest -L ./ -o libtest // 此处与静态库相同
// main.c 主函数所在文件
// -ltest -l 表示要链接 libtest.so(去头去尾)
// -L ./ -L 是指定 gcc 编译器寻找静态库的路径(-L ./ 指定为当前路径),否则默认在 /usr/lib 或 usr/local/lib 路径下寻找
此时尚不能直接运行:
直接运行时:
./libtest // 直接运行
./libtest: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory // 系统提示
方案1:需要将动态库文件放到 /usr/lib 路径下(此操作需要获取权限)
cp libtest.so /usr/lib // 此操作需要先输入指令 su,再输入密码,以获取 root 权限,输入指令 exit 退出
sudo cp libtest.so /usr/lib // 或
方案2:指定动态库的搜索路径
export LD_LIBRARY_PATH=/指定路径(pwd) // 通过环境变量 LD_LIBRARY_PATH 指定动态库搜索路径,只有临时作用(仅对一个终端有效)
// 或创建一个 shell 脚本文件 xxx.sh(内容如下):
export LD_LIBRARY_PATH=/指定路径(pwd)
./libtest
// 为脚本文件增加可执行权限:
chmod +x xxx.sh
// 执行脚本文件:
./xxx.sh
4、 -L,-I,-l 的区别:
-I
(大写 i ):后面存放头文件的路径,第一个寻找头文件的目录-L
:后面的路径存放库文件的地址,第一个寻找库文件的目录-l
(小写 L):后面存放动态库的名字,编译时寻找相应动态库文件