如何将char数组转换为C中的函数指针?

时间:2011-12-14 21:58:56

标签: c linux string casting function-pointers

是否可以使用强制转换为函数指针赋值字符串或字符串数​​组然后运行它?

我已经定义了一些函数int f1();int f2();,依此类推

main()函数中,我读了一个字符串fct_name并声明了一个指向函数int (*pv)();的指针

我需要做这样的事情:

fct_name可以包含值“f1”,“f2”等等。

pv = (some sort of cast)fct_name;

pv();

我的观点是我想避免使用条件指令来支持直接赋值(因为我的程序中有大量函数)

代码显然必须运行。

3 个答案:

答案 0 :(得分:1)

Carey答案的变体,以防你使用* nix系统。 dlopen()打开你的图书馆。 RTLD_LAZY告诉加载器不要立即解决所有库的符号,并等待您尝试访问它们。 dlsym()查找有问题的符号。

修改:更新了代码段以更好地符合您的说明:

#include <dlfcn.h>

int main(int argc, char *argv[])
{
    void *handle = dlopen("libexample.so", RTLD_LAZY);
    if (handle == NULL) {
        // error
    }

    char fct_name[64];

    // read input from terminal here

    void *func = dlsym(handle, fct_name);

    if (func != NULL) {
        // call function here; need to cast as appropriate type
    }
}

libexample.so将是一个包含您的函数的库,编译为共享库,如下所示:

gcc -Wall -o libexample.so example.c -shared -fPIC

话虽这么说,如果你要编译像这样的共享库的麻烦,你可能只想调用二进制文件中的函数。如果在编译时链接库,则可以这样做:

gcc -Wall -o test test.c -L. -lexample

-L.告诉链接器在当前目录(.)中查找库,-lexample告诉它链接名为“libexample.so”的库。如果这样做,您可以直接在程序中调用库函数。

答案 1 :(得分:1)

假设您没有外部库并且正在尝试调用可执行文件中声明的函数,您可以自己进行查找

#define REGISTER_FUNC(name)  {#name, name}

struct funclist
{
    const char* name;
    void (*fp)(void);  //or some other signature
};

struct funclist AllFuncs[] = {
    REGISTER_FUNC(f1),
    REGISTER_FUNC(f2),
    REGISTER_FUNC(f3),
    {NULL,NULL}  //LAST ITEM SENTINEL
 };

现在,您可以在fct_name中查找变量AllFuncs。如果数字很小,您可以使用线性搜索,或者将它们全部插入到哈希表中以进行O(1)查找。

或者,如果您的姓名真的是f1f2等,您可以这样做

   void (*FuncList)(void)[]  = {NULL, f1,f2,f3};
   ...
   int idx = atol(fct_name+1);
   if (idx && idx < MAX_FUNCS)  
       FuncList[idx]();

答案 2 :(得分:0)

您不能仅仅因为数组恰好包含函数名称而将char数组转换为函数。你需要做的是将你的函数放在DLL中,然后执行以下操作:

HMODULE dll = LoadLibrary("foo.dll");
pv func = (pv)GetProcAddress(module, fct_name);