linux下的插件
linux下的插件使用举例: 通过选取插件中的运算方式, 列出使得(5_3)_2 == 4等式成立的全部运算组合.
op.c
// (5 _ 3) _ 2 == 4 #include <stdio.h> #include <glob.h> #include <string.h> #include <dlfcn.h> #ifndef PATH #define PATH "./plugin/*.plugin" #endif typedef int opt_t(int, int); typedef struct { void *handle; opt_t *op; char ch; int inuse; } oper_t; #define MAX 10 int main(void) { oper_t oparr[MAX]; glob_t globbuf; int ret, i, j; void *tmp; memset(oparr, '\0', sizeof(oparr)); ret = glob(PATH, 0, NULL, &globbuf); //all files that matched pathname are stored in globbuf for (i = 0; i < globbuf.gl_pathc; ++i) { oparr[i].handle = dlopen(globbuf.gl_pathv[i], RTLD_LAZY); if (!oparr[i].handle) { fprintf(stderr, "dlopen error.\n"); return -1; } oparr[i].op = dlsym(oparr[i].handle, "func"); tmp = dlsym(oparr[i].handle, "symbol"); oparr[i].ch = ((char (*)(void))tmp)(); //oparr[i].ch = ((char (*)(void))dlsym(oparr[i].handle, "symbol"))(); oparr[i].inuse = 1; } globfree(&globbuf); for (i = 0; i < MAX; ++i) { if (oparr[i].inuse == 0) { continue; } for (j = 0; j < MAX; ++j) { if (oparr[j].inuse == 0) { continue; } if (oparr[j].op(oparr[i].op(5, 3), 2) == 4) { printf("(5 %c 3) %c 2 == 4\n", oparr[i].ch, oparr[j].ch); } } } for (i = 0; i < MAX; ++i) { if (oparr[i].inuse == 0) { continue; } dlclose(oparr[i].handle); } return 0; }
在没有插件时代码执行输出如下:
在plugin目录中添加如下文件, 并编译生成动态库文件:
add.c
int func(int a, int b) { return a + b; } char symbol(void) { return '+'; }
sub.c
int func(int a, int b) { return a - b; } char symbol(void) { return '-'; }
mul.c
int func(int a, int b) { return a * b; } char symbol(void) { return '*'; }
div.c
int func(int a, int b) { return a / b; } char symbol(void) { return '/'; }
mod.c
int func(int a, int b) { return a % b; } char symbol(void) { return '%'; }
power.c
int func(int a, int b) { int i, sum; for (i = 0, sum = 1; i < b; ++i) { sum *= a; } return sum; } char symbol(void) { return '^'; }
输出如下:
此例中, 程序通过glob()函数, 找到所有匹配的文件. 通过dlsym()从匹配到的文件中逐个查询指定符号的值. 并将查询结果记录下来.
用记录下来的查询结果, 对给出的数字进行穷举匹配, 并判断匹配结果. 如果结果为真就打印匹配结果.