C 如何使用宏调用函数?

C 如何使用宏调用函数?,c,macros,c-preprocessor,C,Macros,C Preprocessor,我想根据func\u namestring调用函数。 我的代码如下: #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_";

我想根据
func\u name
string调用函数。 我的代码如下:

#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\u func(print\u hello)
那样工作。但预处理器对我的代码的处理方式类似于调用func(“print\u hello”)。如何在C中使用宏进行例外?或者使用C是不可能的?

您不能这样做。func_name的值在运行时是已知的(即使它是const char*),但您需要确定在预编译时调用什么。您应该将您的cpp宏转换为不同的内容(例如if/switch语句或使用间接寻址)。

然后代码的问题是,
func\u 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);
};
但不可能在宏参数中使用字符串值,就像在代码段中一样

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

#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);
};

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

也许您可以看看dlsym()

我不确定我是否真正理解这个问题,但是如果您想在运行时“构建”函数名,然后调用相应的函数,那么使用dlsym()应该是可能的

/*编译时使用:gcc-example.c-ldl-rdynamic*/
#包括
#包括
int print_hello(无效)
{
返回printf(“hello\n”);
}
int main(int argc,char*argv[])
{
const char*name=“print\u hello”;
如果(argc==42)
print_hello();/*用于编译器不删除处的print_hello
*本例中的编译时优化*/
void*handle=dlopen(NULL/*self*/,RTLD_NOW);
int(*f)(无效)=dlsym(句柄、名称);
f();
返回dlclose(手柄);
}

我认为这是不可能的。在这个程序被编译成没有任何标签信息的二进制可执行程序(用于调试)之后,系统应该如何知道要调用的正确函数?使用宏是不可能的,至少宏本身是不可能的。可以在字符串和函数指针之间创建某种映射。唯一的方法是将宏扩展为一组语句(可能包括函数调用),从而在运行时完成映射。