在C中获取带前缀的所有函数

时间:2014-06-04 17:30:00

标签: c posix function-pointers

是否可以获取具有前缀的函数的函数指针?起初我认为编译过程中c函数的名称丢失了。但是,dlsym返回指向指定名称函数的指针。

所以如果有办法做某事:

void * handle = dlopen(0, RTLD_NOW|RTLD_GLOBAL);
*(void **)(&fptr);
while(fptr = dlsym(handle, "prefix*")) {
   fptr(args);
}

2 个答案:

答案 0 :(得分:0)

为什么不做这样的事情:

#include <stdio.h>

void funcA(int n) { printf("funcA: %d\n", n); }
void funcB(int n) { printf("funcB: %d\n", n); }
void funcC(int n) { printf("funcC: %d\n", n); }

void (*funcs[3]) (int n) = {
    funcA,
    funcB,
    funcC
};

int main() {
    int i;
    for (i = 0; i < sizeof funcs / sizeof *funcs; ++i)
        funcs[i](i);
    return 0;
}

答案 1 :(得分:0)

这不是一种内置方式,我认为没有内置方式......你可以解析nm,但这很难吃。

但如果您正在构建一个插件拱形,您可以使用已知的符号来获取所有符号。

lib.c

char ** functions()
{
    static char * f[3] = {"function1","function2",NULL};
    return f;
}

void function1()
{
    printf("function1\n");
}

void function2()
{
    printf("function2\n");
}

的main.c

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <errno.h>

typedef char ** (*functions)(void);
typedef void (*voidFunc)(void);

int main(int argc, const char * argv[])
{
    void * ref = dlopen("/abs/path/to/libExample.dylib",  RTLD_LAZY | RTLD_LOCAL);
    if (!ref)
    {
        printf("filed to open dylib: %i",errno);
    }

    functions f = dlsym(ref, "functions");

    if (f)
    {
        char** fnames = f();
        char * fname = NULL;
        for (int i = 0; 1 ; i++)
        {
            fname = fnames[i];
            if (fname) {
                voidFunc g = dlsym(ref, fname);
                if (g)
                {
                    g();
                }
            }else{
                break;
            }
        }
    }
    dlclose(ref);
    return EXIT_SUCCESS;
}

输出:

function1
function2
Program ended with exit code: 0

不是linux方式,但在OS X上有一些额外的东西可能会更容易:

/*
 * Structure filled in by dladdr().
 */
typedef struct dl_info {
        const char      *dli_fname;     /* Pathname of shared object */
        void            *dli_fbase;     /* Base address of shared object */
        const char      *dli_sname;     /* Name of nearest symbol */
        void            *dli_saddr;     /* Address of nearest symbol */
} Dl_info;

extern int dladdr(const void *, Dl_info *);