一个so调用另外一个so中的函数。
通过函数dlopen打开指定的动态链接库,得到句柄后,再通过dlsym函数获取动态库中的函数地址,获得函数地址后进行调用。
1.编写calculate.c
int add(int a,int b){
return (a+b);
}
2.将calculate.c编译成libcalculate.so
gcc -fPIC -shared calculate.c -o libcalculate.so
-fPIC 压制警告
-shared 动态库
-o 生成目标的文件名
3.编写main.c
#include<stdio.h>
#include<stdlib.h>
#include<dlfcn.h>
typedef int (*ADD)(int, int);
int main(){
//打开一个动态链接库,并返回动态链接库的句柄
void *handle = dlopen("./libcalculate.so", RTLD_LAZY);
ADD add = NULL;
//获取函数地址
*(void **)(&add) = dlsym(handle, "add");
int result = add(8,8);
printf("Add result:%d\n", result);
return 0;
}
相关函数说明:
(1).void *dlopen(const char *filename, int mode);
打开一个动态链接库,并返回动态链接库的句柄。
mode是打开方式。
RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用总是立即解析)。
RTLD_NOW: 需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
(2).void *dlsym(void *handle, const char *symbol);
根据 动态链接库 操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。
handle:由dlopen打开动态链接库后返回的指针;
symbol:要求获取的函数或全局变量的名称。(本例中是函数add的名称)
4.编译成可执行文件
gcc -rdynamic -o main main.c -ldl
(1).选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中(目的是能够通过使用 dlopen 来实现向后跟踪)
(2).如果程序中使用dlopen、dlsym、dlclose、dlerror 显示加载动态库,需要设置链接选项 -ldl
5.运行结果

网友评论