获取通过宏生成的函数的地址

时间:2013-01-31 15:09:05

标签: c++ macros function-pointers

我尝试使用通过宏生成函数的代码,如下所示:

文件A(提供的文件我不能在这里更改任何内容):

#define FUNCTION_GENERATOR(NUM) \
void MyGeneratedFunctionNo##NUM##(void) \
{ \
     another_function_call(NUM); \
} \

FUNCTION_GENERATOR(1)
FUNCTION_GENERATOR(2)
FUNCTION_GENERATOR(3)

文件B(我的文件,我想使用文件A中生成的函数的函数指针):

typedef void (*function_ptr) (void);
function_ptr func_array[3];
func_array[0] = MyGeneratedFunctionNo1;
func_array[1] = MyGeneratedFunctionNo2;
func_array[2] = MyGeneratedFunctionNo3;
...

当然,编译器抱怨没有定义MyGeneratedFunctionNo1,MyGeneratedFunctionNo2,MyGeneratedFunctionNo3。

有没有办法使用函数指针 生成函数?

2 个答案:

答案 0 :(得分:2)

就像其他任何功能一样,您必须声明它们。这通常在头文件中完成。

您可以直接执行此操作,也可以定义类似于定义功能的宏。

具体而言,将其放在一个头文件中,您在两者中包含您定义函数的文件以及您使用它们的文件中的文件:

extern void MyGeneratedFunctionNo1(void);

答案 1 :(得分:2)

问题本身与函数指针无关。您将无法以任何方式从其他翻译单元访问这些函数,指针与否,因为它们未在其他翻译单元中声明。

典型的基于宏的技术意味着提供和使用两个宏:一个用于生成声明,一个用于生成定义

#define FUNCTION_GENERATOR_DECL(NUM) \
void MyGeneratedFunctionNo##NUM(void);

#define FUNCTION_GENERATOR_DEF(NUM) \
void MyGeneratedFunctionNo##NUM(void) \
{ \
     another_function_call(NUM); \
}

之后,您在某些实现文件中使用“定义”宏实例化(正如您已经做过的那样)

FUNCTION_GENERATOR_DEF(1)
FUNCTION_GENERATOR_DEF(2)
FUNCTION_GENERATOR_DEF(3)

并且您通常将“声明者”宏实例放入某个头文件中。

FUNCTION_GENERATOR_DECL(1)
FUNCTION_GENERATOR_DECL(2)
FUNCTION_GENERATOR_DECL(3)

P.S。另外,请注意@James Kanze在评论中提到的一个重要的微妙点(我最初错过了)。 ##运算符不得用于形成无效的预处理标记。在预处理器中,语法(是一个单独的独立预处理标记(标点符号),而函数名称也是一个单独的独立预处理标记(标识符)。如果您尝试使用(运算符强制将函数名称连接到##,则最终会得到无效的预处理标记和未定义的行为。

不要将(连接到函数名称。从宏定义中删除第二个##。没有它,它将按预期工作。