库文件主要分为:
静态库和共享库
静态库:
表示将库文件指令直接复制到调用文件中,
优点是:效率比较高,并且可以脱离库文件;
缺点:让调用文件显得比较大,不利于修改
共享库:
表示将库文件指令的地址复制到调用文件中,
有点是:调用文件比较小,有利于修改;
缺点是:效率比较低,不可以脱离库文件
静态库的调用流程
(1)编写源程序 vi xxx.c
(2)只编译不链接生成目标文件 cc -c xxx.c
(3)连接静态库文件
cc xxx.o -l 库名 -L 库文件的路径
2.4 共享库的生成流程
(1)编写源程序 vi add.c
(2)只编译不链接 cc -c -fpic add.c
(3)生成共享库文件
cc -shared add.o -o lib库名.so
2.5 共享库的调用流程
(1)编写源程序 vi main.c
(2)只编译不链接 cc -c main.c
(3)链接共享库文件
cc main.o -l 库名 -L 库文件的位置
注意:
要求必须配置环境变量 export LD_LIBRARY_PATH=.
共享库分为隐式调用和显式调用
隐式调用
也称为共享库的静态加载,其中动态库函数在应用程序开始的时候执行时会自动载入内存,进程结束时又自动卸载。
显式调用
也称为共享库的动态加载,应用程序可在其任意运行期间载入或释放动态库所占用的内存空间
显式调用的使用方法:
打开动态库
#include<dlfcn.h>
void *dlopen(const char* pathname,int mode)
成功返回指向动态库的句柄,否则返回NULL
pathname 带路径的动态库名称
mode 动态库加载方式
RTLD_LAZY:动态库的对象符号在被调用时解析
RTLD_NOW:动态库对象的所有符号在函数dlopen返回前被解析
获得动态库对象地址
#include<dlfcn.h>
void *dlsym(void *handle,const char* name);
成功返回该对象的地址,否则返回NULL,由于返回值是 void *,可能实际运行时需要做类型转换
handle 由dlopen返回成功加载动态库的句柄
name 使用对象的名称(动态库中包含的函数或则时变量)
关闭动态库
#include<dlfcn.h>
int dlclose(void *handle);
成功返回0,不成功返回非0;
错误检查
#include<dlfcn.h>
char *dlerror(void)
该函数会返回最近的一次操作动态库的错误信息,无错误发生时返回NULL
函数dlerror执行后会将错误信息重置为NULL,如果连续两次无间隔调用dlerror,后一次的调用结果是NULL