【摘要】
本文简答介绍,怎样使用 dlopen() 函数;
来调用.so 库文件,以及引用他所提供的API接口
直接上程序
此处以 调用手机vendor分区库 mylib.so中的,int my_func(char*, int) 函数为例:
#include <stdio.h>
#include <dlfcn.h>
int open_lib_func();
int main()
{
open_lib_func();
return 0;
}
#define OBJ_LIB_64 = "/vendor/lib64/mylib.so"
#define OBJ_LIB_32 = "/vendor/lib32/mylib.so"
int (*my_func)(char*, char*);
static void* lib_handle = NULL;
int open_lib_func()
{
int ret = -1;
const unsigned int bind_flags = RTLD_LAZY;
/* try openint 32 bit library first */
lib_handle = dlopen(OBJ_LIB_32, bind_flags); /**********首先尝试调用32位库**********/
if (NULL == lib_handle) {
/* try opening 64 bit library then */
LOG(DEBUG, "open lib %s error!!", OBJ_LIB_32);
lib_handle = dlopen(OBJ_LIB_64 , bind_flags);
if (NULL == lib_handle ) {
LOG(DEBUG, "open lib %s error!!", OBJ_LIB_64); /**********32位库调用失败后,调用64位库**********/
goto return_ret;
}
}
if(NULL != lib_handle)
{
my_func = (int (*)(char*, char*))dlsym(lib_handle, "my_func"); /**********引用函数指针**********/
if(NULL == my_func)
{
LOG(DEBUG, "reflect my_func error");
goto return_ret;
}
}
ret = my_func("para1", "para2");
return_ret:
LOG(DEBUG, "ret = %d", ret);
if(NULL != lib_handle)
{
dlclose(lib_handle); /**********关闭库**********/
lib_handle = NULL;
}
return ret;
}
void *dlopen(const char *filename, int flag);
其中flag有:
1、RTLD_LAZY:
在dlopen返回前,动态库中存在的未定义的变量(如extern,也可以是函数)不执行解析,就是不解析其地址;
2、RTLD_NOW:
与上面不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在会返回NULL,错误为:
: undefined symbol: xxxx…
3、RTLD_GLOBAL:
它的含义是使得库中的解析的定义变量在随后的随后其它的链接库中变得可以使用。