怎样动态调用.so文件中的类方法
2018-09-30 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
向TA提问 私信TA
知道合伙人数码行家
采纳数:117538
获赞数:517174
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。
向TA提问 私信TA
关注
展开全部
相关接口:
#include <dlfcn.h>void *dlopen(const char *filename, int flag);char *dlerror(void);void *dlsym(void *handle, const char *symbol);int dlclose(void *handle);123456789
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}#endif123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
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#endif1234567891011121314151617181920212223242526
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;
}12345678910111213141516171819202122232425262728293031
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;
}12345678910111213141516171819202122232425262728293031
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;
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
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
123456
引用:
百度 dlopen(3) - Linux man page
http://tldp.org/HOWTO/C++-dlopen/
错误:
未找到符合
该函数的定义没有链接进.so文件中时,在链接时加上-Wl,-z -Wl,defs参数,可以避免这个问题
#include <dlfcn.h>void *dlopen(const char *filename, int flag);char *dlerror(void);void *dlsym(void *handle, const char *symbol);int dlclose(void *handle);123456789
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}#endif123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
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#endif1234567891011121314151617181920212223242526
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;
}12345678910111213141516171819202122232425262728293031
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;
}12345678910111213141516171819202122232425262728293031
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;
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
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
123456
引用:
百度 dlopen(3) - Linux man page
http://tldp.org/HOWTO/C++-dlopen/
错误:
未找到符合
该函数的定义没有链接进.so文件中时,在链接时加上-Wl,-z -Wl,defs参数,可以避免这个问题
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询