1.库的概念
库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。即库就是.o文件的集合。
2.库的分类:
静态库和动态库(共享库)
静态库:在程序编译时会被连接到目标代码中,程序运行时不再需要该静态库。
动态库(共享库):在程序运行时并不会被连接到目标代码中,而是在程序运行时才会被载入,因此在程序运行时还需要动态库存在,因此代码体积较小。
静态库的创建:
创建静态库用ar命令,它将很多的.o转换成.a
例:将两个打印函数封装成一个静态库
第一个函数printf1.c
#include <stdio.h>
void printf1(void)
{
printf("hello\n");
}
第二个函数printf2.c
#include <stdio.h>
void printf2(void)
{
printf("world\n");
}
要使用这两个函数最好在使用一个头文件来进行声明
头文件 printf.h
#ifndef _PRINTF_H
#define _PRINTF_H
void printf1(void);
void printf2(void);
#endif
主函数 main.c
#include "printf.h"
int main()
{
printf1();
printf2();
return 0;
}
先将两个函数编译成.o文件,再使用语句
ar crs libprintf.a printf1.o printf2.o
创建库
静态库文件名的命名规范是以lib为前缀,紧跟着静态库名,扩展名为.a
使用静态链接库
gcc main.c -L. -lprintf 或者 gcc main.c libprintf.a 都可以生成可执行文件a.out
若使用前一种方式就应该加上 -L. 表示在当前目录查找静态库。
再生成可执行文件后再删除库,可执行文件仍可以执行出正确结果。
动态库(共享库)的创建:
还是以上面的例子为例
gcc -fPIC -c printf1.c printf2.c
gcc -shared -o libprintf.so printf1.o printf2.o
可创建共享库
其中的 -fPIC (position independet code) 创建与地址无关的编译程序
动态库文件名的命名形式为 “libxxxx.so” ,后缀名为“.so”
为了让执行文件顺利找到动态库,有以下三种方法:
1.把库拷到/usr/lib或/bin目录下(但不太建议使用,因为这些目录下的多半为系统自带的库);
2.在LD_LIBRARY_PATH环境变量中加上库所在的路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.(表示添加当前目录的路径,且如果以前环境变量中有路径也不会被覆盖掉,而是添加到末尾);
3.添加/etc/ld.so.conf/*.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新(建议自己创建一个my.conf文件来存放路径,其他的文件多也是系统自带的,自己创建的也可以随意修改删除对系统不会有影响);
静态库和动态库的一些区别