参考链接:https://www.cnblogs.com/Anker/p/3746802.html
动态库API介绍
#include <dlfcn.h>
void *dlopen(const char *filename, intflag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,打开模式如下:
RTLD_LAZY 暂缓决定,等有需要时再解出符号
RTLD_NOW 立即决定,返回前解除所有未决定的符号。
dlerror返回出现的错误
dlsym通过句柄和连接符名称获取函数名或者变量名
dlclose来卸载打开的库
dlopen打开模式如下:
测试程序
add.h
int add(int a, int b);
add.c
#include "add.h"
#include <stdio.h>
int add(int a, int b)
{
returna + b;
}
编译动态库
user2@rlk-buildsrv-tf30:~/projects/study/code/dlopen/dll$gcc -fPIC -shared add.c -o libadd.so
user2@rlk-buildsrv-tf30:~/projects/study/code/dlopen/dll$ls
add.c add.h libadd.so main.c
main.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "add.h"
#define SHARE_LIB_PATH "./libadd.so"
typedef int(* handler_t)(int a, int b);
int main(void)
{
inta = 2;
intb = 3;
char*error;
void*dlhandler = NULL;
handler_thandler = NULL;
dlhandler= dlopen(SHARE_LIB_PATH, RTLD_LAZY);
if(!dlhandler){
fprintf(stderr,"%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror();
*(void**) (&handler) = dlsym(dlhandler, "add");
if((error = dlerror()) != NULL) {
fprintf(stderr,"%s\n", error);
exit(EXIT_FAILURE);
}
printf("lkl dladd: %d\n", (*handler)(2,7));
//printf("a+b= %d\n", (add(a, b))); //不能直接调用add函数,否则会报编译错误
return0;
}
user2@rlk-buildsrv-tf30:~/projects/study/code/dlopen/dll$gcc -rdynamic -o main main.c -ldl
user2@rlk-buildsrv-tf30:~/projects/study/code/dlopen/dll$ls
add.c add.h libadd.so main main.c
编译和执行结果
user2@rlk-buildsrv-tf30:~/projects/study/code/dlopen/dll$./main
lkl dladd: 9