1、简介
库文件命名形式
.a 静态链接库
.so动态链接库。形式:[libname.so[主版本号.次版本号.发行号]]
• 静态库有一些缺点:
– 库函数(如printf)被包含在每个运行进程的代码段中,对于并发 运行上百个进程的系统,造成极大的主存资源浪费
– 库函数(如printf)被合并在可执行目标中,磁盘上存放着数千个 可执行文件,造成磁盘空间的极大浪费
– 程序员需关注是否有函数库的新版本出现,并须定期下载、重新编 译和链接,更新困难、使用不便
• 解决方案: Shared Libraries (共享库)
– 是一个目标文件,包含有代码和数据
– 从程序中分离出来,磁盘和内存中都只有一个备份
– 可以动态地在装入时或运行时被加载并链接
– Window称其为动态链接库(Dynamic Link Libraries,.dll文件)
– Linux称其为动态共享对象( Dynamic Shared Objects, .so文件)
2、库文件的制作
自定义一个动态共享库文件:
使用的命令参数简介:
-shared | 链接选项,告诉gcc生成动态库而不是可执行文件 |
-fPIC | PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码 1)保证共享库代码的 位置可以是不确定的 2)即使共享库代码的 长度发生变化,也不会 影响调用它的程序 |
过程
两个.c文件myproc1.c和myproc2.c
打包为共享库mylib.so,命令如下。
gcc –c myproc1.c myproc2.c //编译生成.o文件
gcc -shared -fPIC -o mylib.so myproc1.o myproc2.o //生成*.so文件
注:PIC:Position Independent Code 位置无关码。
加载时动态链接方法:main.c中引用了myproc1.c中函数myfunc1,需要指出目标库mylib.so(C标准库libc.so无需明显指出)
void myfunc1(viod);
int main()
{
myfunc1(); return 0;
}
gcc -c main.c
gcc -o myproc main.o ./mylib.so
运行时动态链:
制作静态库文件
3、库文件的使用
动态链接可以按以下两种方式进行:
先了解两个参数-l和-L
-l (小写的L) | 作用:用来指定程序要链接的库。 用法:-l参数紧接着就是库名 解释:就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。 比如我们自已要用到一个第三方提供的库名字叫libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.so配套的头文件) |
-L | 作用:将 dirname 目录加入到库文件的搜索目录列表中 。 比如某个C文件包含了一个自定义的 *.a、*.so文件,编译时找不到这个自定义的文件,那么就需要用这个参数指定的库文件的路径。 例如-L/usr/mylib |
另外一个 参数-I(大写i),这个是用来指定*.h头文件的路径的参数。
用法示例:
//编译文件,连接libmymath.so动态库,库路径为当前路径
gcc -o test -c main.c -lmymath -L.
• 在第一次加载并运行时进行 (load-time linking).
– Linux通常由动态链接器(ld-linux.so)自动处理 – 标准C库 (libc.so) 通常按这种方式动态被链接
• 在已经开始运行后进行(run-time linking).
– 在Linux中,通过调用 dlopen()等接口来实现
• 分发软件包、构建高性能Web服务器等 在内存中只有一个备份,被所有进程共享,节省内存空间
一个共享库目标文件被所有程序共享链接,节省磁盘空间
共享库升级时,被自动加载到内存和程序动态链接,使用方便
共享库可分模块、独立、用不同编程语言进行开发,效率高
第三方开发的共享库可作为程序插件,使程序功能易于扩展