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
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#define LIB_CACULATE_PATH "./libdl.so"
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