目录
1.定义
库文件本质上是经过编译后生成的可被计算机执行的二进制代码,但注意库文件不能独立运行,库文件是需要加载到内存中才能执行的,库文件大量的存在于windows, Linux,MacOs软件平台上的。
2. 库文件的分类
2.1 静态库
Windows: xxx.lib
Linux: libxxxx.a
2.2 动态库(共享库)
Windows: xxx.dll
Linux: libxxxx.so.major.minor
注意:不同的软件平台因编译器,链接器不同,所生成的库文件是不兼容的
2.3静态库与动态库的区别
a. 静态库在链接时,将库中所有内容包含到最终的可执行程序中的。
b. 动态库在链接时, 将库中的符号信息包含到最终可执行程序中,在程序运行时,才将动态库中符号的具体实现加载到内存中的
2.4静态库与动态库的优缺点
a.静态库:生成的可执行程序体积比较大。
但一旦生成可执行程序,程序运行就不再依赖静态库文件
b.动态库:生成的可执行程序体积比较小,但可执行程序的运行依然要依赖动态库文件。
一旦动态库被加载到内存中,此次动态库可以被多个应用程序共享访问。
3. 库文件创建(产生)
Linux 系统下:
库文件的命名规范: libxxxxx.a libxxxxx.so
3.1 静态库文件的生成
1) 将需要生成库文件对应的源文件(*.c)通过编译(不链接)生成 *.o 目标文件;
2) 用 ar 将生成的 *.o 打包生成 libxxxxx.a ;
例子:
gcc -c fun.c -o fun.o
ar -csr libmyfun.a fun.o
静态库文件使用:
gcc main.c -o app -lmyfun -L./
3.2 动态库文件的生成
1) 利用源文件(*.c)通过编译(不链接)生成位置无关的 *.o 目标文件
2) 将目标文件链接为.so文件
例子:
gcc -fPIC -c fun.c -o fun.o
gcc -shared -o fun.o -o libdlfun.so
3)动态库文件使用
gcc main.c -o app -ldlfun -L./
注意:如果在代码编译过程/运行中链接了库文件,系统会到/lib 和 /usr/lib 目录下查找库文件,所以建议直接将库文件放置在 /lib 和 /usr/lib,否则系统可能无法找到库文件,造成编译/运行错误。
扩展:
a.查看应用程序(例:main)依赖的动态库:
ldd main
b.动态库使用方式:
①编译时链接动态库,运行时系统自动加载动态库;
②程序运行时,手动加载动态库;
c.实现:
涉及到内容:
头文件 #include <dlfcn.h>
接口函数:dlopen dlclose dlsym
依赖库: -ldl
句柄 handler: 资源的标识
int main(int argc,char** argv)
{
void* handler = dlopen("./libdlfun.so",RTLD_LAZY); //加载动态时,延时绑定符号
if(handler == NULL)
{
fprintf(stderr,"dlopen:%s\n",dlerror());
return -1;
}
int(*paddr)(int,int) = (int(*)(int,int))dlsym(handler,"max");
if(paddr == NULL)
{
fprintf(stderr,"dlsym:%s\n",dlerror());
dlclose(handler);
return -1;
}
printf("max=%d\n",paddr(7,3));
dlclose(handler);
return 0;
}