linux 程序动态调用.so文件中的函数
来源:互联网 发布:seo建站 编辑:程序博客网 时间:2024/06/13 15:56
相关接口:
#include <dlfcn.h>void *dlopen(const char *filename, int flag);char *dlerror(void);void *dlsym(void *handle, const char *symbol);int dlclose(void *handle);
eg:
dlapi.c
/*[root@localhost eg]# gcc main.c -Wl,-rpath=./ -ldl -D_TEST[root@localhost eg]# g++ main.c -Wl,-rpath=./ -ldl -D_TEST*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <dlfcn.h>#ifdef __cplusplusextern "C" {#endiftypedef int (*PCall_func0)();typedef int (*PCall_func1)(void *);typedef int (*PCall_func2)(void *, void *);typedef int (*PCall_func3)(void *, void *, void *);typedef int (*PCall_func4)(void *, void *, void *, void *);int dynamic_call_library_func0(char *libName, char *funcName) { void *handle; void *error; PCall_func0 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库 handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000; } dlerror(); //获取一个函数 selffunc = (PCall_func0)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001; } ret = selffunc(); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 dlclose(handle); return ret;}int dynamic_call_library_func1(char *libName, char *funcName, void *argv1) { void *handle; void *error; PCall_func1 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库 handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000; } dlerror(); //获取一个函数 selffunc = (PCall_func1)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001; } ret = selffunc(argv1); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 dlclose(handle); return ret;}int dynamic_call_library_func2(char *libName, char *funcName, void *argv1, void *argv2) { void *handle; void *error; PCall_func2 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库 handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000; } dlerror(); //获取一个函数 selffunc = (PCall_func2)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001; } ret = selffunc(argv1, argv2); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 dlclose(handle); return ret;}int dynamic_call_library_func3(char *libName, char *funcName, void *argv1, void *argv2, void *argv3) { void *handle; void *error; PCall_func3 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库 handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000; } dlerror(); //获取一个函数 selffunc = (PCall_func3)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001; } ret = selffunc(argv1, argv2, argv3); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 dlclose(handle); return ret;}int dynamic_call_library_func4(char *libName, char *funcName, void *argv1, void *argv2, void *argv3, void *argv4) { void *handle; void *error; PCall_func4 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库 handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000; } dlerror(); //获取一个函数 selffunc = (PCall_func4)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001; } ret = selffunc(argv1, argv2, argv3, argv4); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 dlclose(handle); return ret;}#ifdef _TESTint main(int rgvs, char **rgva){char buff[]="asdfasdf";int x=8;printf("main gcc build\n");printf("g_path gcc libeggcc.so char *\n"); dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show1", buff);printf("g_path g++ libegg++.so char *\n"); dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show1", buff);printf("../lib path gcc libeggcc.so char *\n"); dynamic_call_library_func1("libeggcc.so", "show1", buff);printf("../lib path g++ libegg++.so char *\n"); dynamic_call_library_func1("libegg++.so", "show1", buff);printf("g_path gcc libeggcc.so int\n"); dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show2", &x);printf("g_path g++ libegg++.so int\n"); dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show2", &x);printf("../lib path gcc libeggcc.so int\n"); dynamic_call_library_func1("libeggcc.so", "show2", &x);printf("../lib path g++ libegg++.so int\n"); dynamic_call_library_func1("libegg++.so", "show2", &x); return 0;}#endif#ifdef __cplusplus}#endif
dlapi.h
#ifndef _DL_API_H#define _DL_API_H#ifdef __cplusplusextern "C" {#endif/*使用g++编译的.so库中,函数前必须添加 exter "C" 函数参数类型为指针,不或以为引用*/int dynamic_call_library_func0(char *libName, char *funcName) ;int dynamic_call_library_func1(char *libName, char *funcName, void *argv1) ;int dynamic_call_library_func2(char *libName, char *funcName, void *argv1, void *argv2) ;int dynamic_call_library_func3(char *libName, char *funcName, void *argv1, void *argv2, void *argv3) ;int dynamic_call_library_func4(char *libName, char *funcName, void *argv1, void *argv2, void *argv3, void *argv4) ;#ifdef __cplusplus}#endif#endif
eg.c
/*[root@localhost eg]# gcc eg.c -fPIC -shared -o libeggcc.so[root@localhost eg]# g++ eg.c -fPIC -shared -o libegg++.so*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>int show1(char *src){ printf("%s\n", src); return 100;}int show2(int *x){ printf("%2d\n", *x); return 101;}
eg.cpp
/*[root@localhost eg]# gcc eg.c -fPIC -shared -o libeggcc.so[root@localhost eg]# g++ eg.c -fPIC -shared -o libegg++.so*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>extern "C" int show1(char *src){ printf("%s\n", src); return 100;}extern "C" int show2(int *x){ printf("%2d\n", *x); return 101;}
main.c
/*[root@localhost eg]# gcc main.c -Wl,-rpath=./ -ldl -D_TEST[root@localhost eg]# g++ main.c -Wl,-rpath=./ -ldl -D_TEST*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <dlfcn.h>#include "dlapi.h"int main(int rgvs, char **rgva){char buff[]="asdfasdf";int x=8;int ret;printf("main gcc build\n");printf("\ng_path gcc libeggcc.so char *\n"); ret = dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show1", buff);printf("\ng_path g++ libegg++.so char *\n"); dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show1", buff);printf("\ncur lib path gcc libeggcc.so char *\n"); dynamic_call_library_func1("libeggcc.so", "show1", buff);printf("\ncur lib path g++ libegg++.so char *\n"); dynamic_call_library_func1("libegg++.so", "show1", buff);printf("\ng_path gcc libeggcc.so int\n"); dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show2", &x);printf("\ng_path g++ libegg++.so int\n"); dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show2", &x);printf("\ncur lib path gcc libeggcc.so int\n"); dynamic_call_library_func1("libeggcc.so", "show2", &x);printf("\ncur path g++ libegg++.so int\n"); dynamic_call_library_func1("libegg++.so", "show2", &x); return 0;}
makefile
all: gcc eg.c -fPIC -shared -o libeggcc.so g++ eg.cpp -fPIC -shared -o libegg++.so gcc dlapi.c -ldl -fPIC -shared -o libdlapi.so g++ main.c -L. -ldlapi -Wl,-rpath=./ -Wl,-rpath=./lib
引用:
百度 dlopen(3) - Linux man page
http://tldp.org/HOWTO/C++-dlopen/
错误:
未找到符合
该函数的定义没有链接进.so文件中时,在链接时加上-Wl,-z -Wl,defs参数,可以避免这个问题
0 0
- linux 程序动态调用.so文件中的函数
- linux 动态调用 .so 库文件中的函数
- Linux 调用动态库(.SO文件)总结 (特指调用so文件中的函数)
- linux中动态调用*.so库文件
- linux 调用动态库so文件
- linux 调用动态库so文件
- linux调用动态库so文件
- linux 调用动态库so文件
- linux .so 文件中函数名称和程序中的函数名称相同
- 动态库(.so)函数调用
- linux下调用动态链接库so文件
- Linux 调用动态库(.SO文件)总结
- Linux 调用动态库(.SO文件)总结
- Linux 调用动态库(.SO文件)总结
- linux与windows调用动态库so dll文件
- linux-C直接调用SO动态库和生成SO动态库的函数
- linux调用.so动态库
- Linux编译.so文件,调用.so文件
- android app与h5交互
- ElasticSearch(七)-结构化查询
- [Android设计模式]Android退出应用程序终极方法
- Leetcode 169. Majority Element
- 杂七杂八
- linux 程序动态调用.so文件中的函数
- 75. Trapping Rain Water
- Android一键换肤功能:一种简单的实现
- HDU3926 Hand in Hand(并查集)
- CentOS-6.3安装配置Tomcat-7
- 职场面试:如何快速提升你的通过率?
- hdu 1556 树状数组(区间更新,单点求和)
- Java 集合类
- HDU5543