如何使用宏来调用函数?

时间:2015-11-01 13:11:26

标签: c macros c-preprocessor

我想根据func_name字符串调用函数。 我的代码如下:

#define MAKE_FUNCNAME func_name##hello

void call_func(void* (*func)(void))
{
    func();
}

void *print_hello(void)
{
    printf("print_hello called\n");
}

int main(void)
{
    char func_name[30] = "print_";

    call_func(MAKE_FUNCNAME);
    return 0;
}

但是这段代码不起作用。我希望代码像call_func(print_hello)一样工作。但预处理器将我的代码视为call_func("print_hello")。如何在 C 中使用宏来进行异常处理?或者是否无法使用 C

3 个答案:

答案 0 :(得分:4)

然后,您的代码问题是func_name的值仅在运行时才知道。

但你可以这样:

#define MAKE_FUNCNAME(FUNCNAME) FUNCNAME##hello

void call_func(void* (*func)(void))
{
    func();
}

void *print_hello(void)
{
    printf("print_hello called\n");
}

int main(void)
{
    call_func(MAKE_FUNCNAME(print_));
    return 0;
}

但是不可能在代码片段中的宏参数中使用字符串值。

如果你想使用字符串值获取名字的调用函数,你可以使用一个表来存储函数指针,如下所示:

struct {
    const char *name;
    void (*ptr)(void);
};

您可以使用此结构的数组在运行时使用字符串值查找函数指针。这是使用运行时字符串使用其名称调用函数的最常见解决方案。

答案 1 :(得分:2)

你做不到。 func_name的值在运行时是已知的(即使它是一个const char *),而您想要确定在预编译时调用的内容。您应该将cpp宏转换为不同的东西(例如if / switch语句或使用间接)。

答案 2 :(得分:1)

也许你可以看看dlsym()。

不确定我是否真的理解这个问题,但是如果你想要"建立"在运行时的函数名称然后调用相应的函数,应该可以使用dlsym()

/* compile with: gcc example.c -ldl -rdynamic */
#include <dlfcn.h>
#include <stdio.h>

int print_hello(void)
{
    return printf("hello\n");
}

int main(int argc, char *argv[])
{
    const char *name = "print_hello";
    if (argc == 42) 
        print_hello(); /* for compiler not to remove print_hello at
                        * compile time optimisation in this example*/
    void *handle = dlopen(NULL /* self */, RTLD_NOW);
    int (*f)(void) = dlsym(handle, name);
    f();
    return dlclose(handle);
}