c语言为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。linux提供了加载和处理动态链接库的系统调用,非常方便。
c语言提供api让我们加载动态链接库文件 android 即上的.so文件
dlopen函数以指定模式打开指定的动态链接库文件,并返回一个句柄给dlsym()的调用进程
dlclose 卸载打开的库
dlerror 返回出现的错误
dlsym dlsym通过句柄和连接符名称获取函数名或者变量名
先写一个动态链接文件
int add(int a,int b)
{
return (a + b);
}
int sub (int a, int b)
{
return (a - b);
}
int mul(int a, int b)
{
return (a * b);
}
int div(int a, int b)
{
return (a / b);
}
编译动态链接库文件
gcc -fPIC -shared dl.c -o libdl.so
再写一个主函数 opendl.c
typedef int (*CAC_FUNC )(int , int );
int main()
{
void *handle ;
char *error ;
CAC_FUNC cac_func = NULL;
handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s \n" , dlerror());
exit (EXIT_FAILURE);
}
dlerror();
*( void ** ) (&cac_func) = dlsym(handle, "add" );
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s \n" , error);
exit (EXIT_FAILURE);
}
printf ("add: %d \n" , (*cac_func )(2 ,7 ));
cac_func = (CAC_FUNC)dlsym(handle, "sub" );
printf ("sub: %d \n" , cac_func(9 ,2 ));
cac_func = (CAC_FUNC)dlsym(handle, "mul" );
printf ("mul: %d \n" , cac_func(3 ,2 ));
cac_func = (CAC_FUNC)dlsym(handle, "div" );
printf ("div: %d \n" , cac_func(8 ,2 ));
dlclose(handle);
exit (EXIT_SUCCESS);
}
编译成可执行文件 gcc -rdynamic -o opendl opendl.c -ldl
[root@jaytang dlopen]# ls
dl.c libdl.so opendl opendl.c
执行./opendl
出现如下效果
[root@jaytang dlopen]# ./opendl
add: 9
sub: 7
mul: 6
div: 4
源码见github