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()从匹配到的文件中逐个查询指定符号的值. 并将查询结果记录下来.

用记录下来的查询结果, 对给出的数字进行穷举匹配, 并判断匹配结果. 如果结果为真就打印匹配结果.

posted @ 2016-02-02 00:00  zhanglong71  阅读(544)  评论(0编辑  收藏  举报