您的位置:首页 > 编程语言 > C语言/C++

C语言调用动态库中的函数的方法(dlopen,dlsym等)

2016-03-05 11:51 661 查看
当我们需要使用外部的库(比如XML处理、正则等),除了编译的时候连接该哭外,也可以打开.so的库获取函数地址,传入参数,来调用外部库的函数。

后一种方式可以在程序中用一个统一的结构体来管理。

比如动态库a中有这样一个函数:

extern "C" int QueryResVal(int ClientHandle);


目标:我们通过文档知道该函数作用,需要用到我们自己的程序中。

首先在头文件中定义一个结构体:

typedef int (*QueryResVal)(int ClientHandle);//注意我们自己使用的时候是地址,要带星号
typedef struct _playback_func
{
QueryResVal f_query_res_val
int is_init;//0-未初始化;1-已初始化
}PLAYBACK_FUNC;

static PLAYBACK_FUNC g_playback_func;//一个全局的结构体,需要使用的函数统一在此

struct LibHandle
{
void* handle;
string name;
};//用于调用dlopen的结构体

static LibHandle *so_handle;//用于打开一个动态库,存储句柄
//封装dlopen的调用
static LibHandle* OpenLib(const char* filename, int ldtype = RTLD_LAZY)
{
void* h = dlopen(filename, ldtype);
if (h == NULL)
{
return NULL;
}
LibHandle* handle = new LibHandle;
handle->handle = h;
handle->name = filename;
return handle;
}

static void CloseLib(LibHandle* libhandle)
{
if (libhandle)
{
dlclose(libhandle->handle);
delete libhandle;
}
}
//封装dlsym调用
static void* FindSymbol(LibHandle* libhandle, const char* fun_name)
{
if (!libhandle || libhandle->handle == NULL)
return NULL;
void* p = dlsym(libhandle->handle, fun_name);
if (p == NULL)
printf("%s  Cannot find symbol %s:%d",libhandle->name.c_str(),fun_name,dlerror());
return p;
}


以上是一些封装函数,适用于任何需要调用动态库函数的地方。

下面初始化handle,打开动态库,然后就可以统一初始化想要的函数

int init()
{
int ret = -1;
do
{
g_playback_function.f_query_res_val= (QueryResVal)FindSymbol(so_handle, "QueryResVal");
if_null_break(g_playback_function.f_query_res_val, "libtest.so");
ret = 0;
}
while(0);
return ret;
}


这样就做之后,就可以直接调用结构体中的方法:

int main()
{
init();
int userid = 0;
int ret= g_playback_function.f_query_res_val(userid);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: