我有一个数组(C language),应该在编译时初始化它。
例如:
DECLARE_CMD(f1, arg);
DECLARE_CMD(f2, arg);DECLARE_CMD是从多个文件调用的。
我要把这个做预处理。
my_func_type my_funcs [] = {
&f1,
&f2
}是否可以使用宏将项附加到静态数组中?
我在gcc4上使用gcc4(带有GNU扩展)。
发布于 2010-09-03 07:58:13
注意:在你的问题中,每一行的末尾都有分号。这将严重干扰使用这些宏的任何尝试。因此,这取决于在哪里和如何找到DECLARE_CMD(...)行,以及您是否能够修复分号问题。如果它们只是单独存在于一个专用的头文件中,您可以这样做:
#define DECLARE_CMD(func, arg) &func,
my_func_type my_funcs [] {
#include "file_with_declare_cmd.h"
};...which被转化为:
my_func_type my_funcs [] {
&f1,
&f2,
};请阅读新C: X宏,以获得对此的良好解释。
如果不能去掉分号,将处理如下:
my_func_type my_funcs [] {
&f1,;
&f2,;
};..。这显然是语法错误,所以这是行不通的。
发布于 2016-05-06 22:21:53
是的,您可以在编译时(而不是在运行时)构建动态数组(感谢米切尔·汉弗里斯),其思想是在下面的同一节中声明您的回调:
例子:
假设您有三个文件: a.c、B.C.main.c和i.h。
进入i.h
typedef void (*my_func_cb)(void);
typedef struct func_ptr_s {
my_func_cb cb; /* function callback */
} func_ptr_t;
#define ADD_FUNC(func_cb) \
static func_ptr_t ptr_##func_cb \
__attribute((used, section("my_array"))) = { \
.cb = func_cb, \
}转换为a.c
#include "i.h"
static void f1(void) {
....
}
ADD_FUNC(f1);将转换为b.c
#include "i.h"
static void f2(void) {
....
}
ADD_FUNC(f2);将转换为main.c
#include "i.h"
static void f3(void) {
....
}
ADD_FUNC(f3);
#define section_foreach_entry(section_name, type_t, elem) \
for (type_t *elem = \
({ \
extern type_t __start_##section_name; \
&__start_##section_name; \
}); \
elem != \
({ \
extern type_t __stop_##section_name; \
&__stop_##section_name; \
}); \
++elem)
int main(int argc, char *argv[])
{
section_foreach_entry(my_array, func_ptr_t, entry) {
entry->cb(); /* this will call f1, f2 and f3 */
}
return 0;
}重要
有时编译器会优化开始/结束部分变量,然后删除它们,所以当您尝试使用它们时,您将有一个链接器错误:error LNK2019:未决外部符号.
要解决这个问题,我使用以下方法:
复制两者之间的文本:
==================================================
在一个文件(例如lnk.lds)中,应该是这样的:
用于/* combreloc的-z脚本:合并和排序reloc部分*/
OUTPUT_FORMAT(“elf64 64-x86-64”、“elf64 64-x86-64”、“elf64 64-x86-64”)
.
__start_my_array = .;
.my_array :
{
*(.my_array)
}
__stop_my_array = .;发布于 2010-09-03 08:05:34
是的,这是可能的。通常的技巧是在一个(或多个)包含文件的一个(或多个)中包含所有的DECLARE_CMD(func, args)行,并在不同的地方包含那些对宏有适当定义的行。
例如:
文件“Commands.inc”中:
DECLARE_CMD(f1, args)
DECLARE_CMD(f2, args)在某些源文件中:
/* function declarations */
#define DECLARE_CMD(func, args) my_func_type func;
#include "commands.inc"
#undef DECLARE_CMD
/* array with poiners */
#define DECLARE_CMD(func, args) &func,
my_func_type* my_funcs[] = {
#include "commands.inc"
NULL
};https://stackoverflow.com/questions/3633896
复制相似问题