动态库的静态加载
math.c
#include<stdio.h>
int add(int a,int b)
{
return a+b;
}
show.c
#include<stdio.h>
int show(int a)
{
printf("两数之和:%d",a);
}
编译成目标模块:
gcc -fpic -c math.c -o math.o //自行编写他们的头文件放在同一目录下
gcc -fpic -c show.c -o show.o
链接成共享库
gcc -shared math.o show.o -o libmath.so
libmath.so为动态库,libxxx 其中 xxx 为动态库的名字
将动态库的路径加到环境变量中
在Linux的目录终端运行一下代码
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
. 表示当前目录
在终端运行
gcc main.c libmath.so
生成 a.out 运行./a.out 。完成
动态库动态加载
动态加载是在程序运行期间加载和卸载动态库
Linux中的dl库实现库的动态加载
加载共享库 ---- dlopen
filename:给路径按照路径加载,给文件名就根据LD_LIBRARY_PATH环境变量去查找
flag:加载标志
RTLD_LAZY:延迟加载,什么时候真正使用的时候才加载
RTLD_NOW:立即加载
返回值:
成功返回动态库的句柄,失败返回NULL
获取动态库的的函数地址 ------- dlsym
handle:动态库的句柄
symbol:函数名
返回值:
成功返回函数地址,失败返回NULL
卸载动态库 -------------dlclose
handle:动态库的句柄
获取出错信息 --------- dlerror
返回错误字符串
dmain.c
#include<stdio.h>
#include<dlfcn.h>
typedef int(*PFUNC_CALL)(int,int);
typedef int(*PFUNC_SHOW)(int); //给函数指针定义一个别名 PFUNC_SHOW = int(*)(int)
int main()
{
void *handle = dlopen("./libmath.so",RTLD_LAZY); //加载动态库
if(handle==NULL)
{
printf("dlopen失败:%s\n",dlerror());
return -1;
}
//获取函数地址
PFUNC_CALL add = (PFUNC_CALL)dlsym(handle,"add");
if(add==NULL)
{
printf("dlsym失败:%s\n",dlerror());
return -1;
}
int(*show)(int)= dlsym(handle,"show"); //int(*show)(int) = PFUNC_SHOW
if(add==NULL) // 函数原型 int show(int)
{
printf("dlsym失败:%s\n",dlerror());
return -1;
}
show(add(9,5));
dlclose(handle);
return 0;
}
在终端上编译生成 a.out 文件
gcc dmain.c libmath.so -ldl