gpt4 book ai didi

c - 在 C 中使用宏将项目附加到数组

转载 作者:太空狗 更新时间:2023-10-29 17:23:18 26 4
gpt4 key购买 nike

我有一个数组(C 语言)应该在编译时初始化。

例如:

DECLARE_CMD(f1, arg);
DECLARE_CMD(f2, arg);

DECLARE_CMD 从多个文件调用。

我希望对其进行预处理。

my_func_type my_funcs [] = {
&f1,
&f2
}

可以使用宏将项目附加到静态数组吗?

我在 gcc4 上使用 C99(带有 GNU 扩展)。

最佳答案

是的,您可以在编译时(而不是在运行时)构建动态数组(感谢 Mitchel Humpherys),想法是像这样在同一部分中声明您的回调:

示例:

假设你有三个文件 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, \
}

进入空调

#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: unresolved external symbol ...

为了解决这个问题,我使用了以下方法:

  1. 尝试打印您的链接描述文件:

    gcc -Wl,-详细

复制两者之间的文字:

============================================ ======

在一个文件中(例如 lnk.lds),您应该看到如下内容:

/* -z combreloc 的脚本:合并和排序 reloc 部分 */

OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64","elf64-x86-64")

........

  1. 将您的部分添加到链接描述文件 lnk.lds 在 .data 部分之后,如下所示(我定义的部分在示例中称为 my_array):
  __start_my_array = .;
.my_array :
{
*(.my_array)
}
__stop_my_array = .;
  1. 像这样使用更新后的链接描述文件编译您的程序:

    gcc -O3 -Xlinker -T"lnk.lds"file.c -o 程序

  2. 如果你输入字符串程序| grep "__start_my_array" 你应该找到它。

关于c - 在 C 中使用宏将项目附加到数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3633896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com