大家好,欢迎来到IT知识分享网。
使用so动态库时,可以在编译时链接动态库,也可以在代码运行时动态加载so库。本文主要介绍如何动态加载so库。
常用的函数主要有dlopen,dlysm,dlclose,dlerror。
一、函数介绍
1、dlopen函数
void * dlopen( const char * pathname, int mode)
- 功能:打开动态库返回句柄
- pathname:so动态库的路径,可以是相对路径
- mode:选项配置
常用mode | 功能 |
RTLD_LAZY | 在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址 |
RTLD_NOW |
在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为: : undefined symbol: xxxx……. |
其他mode详解参考 | https://www.cnblogs.com/ho966/p/17366207.html |
- 返回值:动态库的句柄
2、dlsym函数
void *dlsym(void *handle, const char *symbol)
- 功能:根据给定的符号名称查找对应的符号地址,例如函数名会返回函数地址
- handle:dlopen打开的动态库的句柄
- symbol:需要查找的符号名称
- 返回值:symbol符号地址
3、dlclose函数
int dlclose (void *__handle)
- 功能:关闭__handle句柄
4、dlerror函数
char *dlerror (void)
- 功能:检查上次调用是否成功,成功返回NULL,失败返回出错信息
二、实例
1、编译生成so库
#include <stdio.h> /* 加 */ int cal_add(int a,int b) { return (a + b); } /* 减 */ int cal_sub(int a, int b) { return (a - b); } /* 乘 */ int cal_mul(int a, int b) { return (a * b); } /* 除 */ int cal_div(int a, int b) { return (a / b); }
编译,生成自定义的 libcalculate.so 库
$ gcc -fPIC -shared calculate.c -o libcalculate.so
2、动态加载so库
动态加载 libcalculate.so 库,获取 cal_add 加法函数并调用
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> typedef int (*FUNC)(int, int); int main(int argc, char* argv[]) { void *lib; FUNC lib_func = NULL; int temp1, temp2, result; if (argc != 3) { printf("param error!!!"); return -1; } temp1 = strtol(argv[1], NULL, 10); temp2 = strtol(argv[2], NULL, 10); /* 打开动态链接库 */ lib = dlopen("./libcalculate.so", RTLD_LAZY); if (lib == NULL) { printf("%s dlopen failed: %s\n", "libcalculate.so", dlerror()); } /* 获取库函数 */ lib_func = dlsym(lib, "cal_add"); if (!lib_func) { printf("can't find module symbol: %s\n", dlerror()); } /* 调用库函数 */ result = lib_func(temp1, temp2); printf("result: %d\n", result); return 0; }
编译应用程序, 需要加上”-ldl“库,才能调用dlopen、dlclose等函数
$ gcc -o test_app main.c -ldl #编译生成 test_app 可执行文件
3、测试结果
./test_app 3 8 #运行应用
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/126299.html