c/c++语言开发共享使用宏将项目附加到具有宏的数组中

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

例如:

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

从多个文件中调用DECLARE_CMD。

我想要对它进行预处理。

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

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

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

    注意:在您的问题中,每行末尾都有分号。 这将严重干扰任何使用这些宏的尝试。 所以这取决于找到DECLARE_CMD(...)行的位置和方式,以及是否可以修复分号问题。 如果它们只是一个专用的头文件,你可以这样做:

     #define DECLARE_CMD(func, arg) &func, my_func_type my_funcs [] { #include "file_with_declare_cmd.h" }; 

    ……变成了:

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

    阅读新C:X宏以获得对此的详细解释。

    如果你无法摆脱分号,这将被处理为:

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

    …这显然是语法错误,所以这不起作用。

    是的,你可以在编译时(而不是在运行时)构建动态数组(感谢Mitchel Humpherys),我们的想法是在同一部分声明你的回调,如下所示:

    例:

    假设你有三个文件ac,bc main.c和ih

    进入

     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 "ih" static void f1(void) { .... } ADD_FUNC(f1); 

    进入公元前

     #include "ih" static void f2(void) { .... } ADD_FUNC(f2); 

    进入main.c

      #include "ih" 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; } 

    重要

    有时编译器会优化开始/结束部分变量,它会将它们清除掉,因此当您尝试使用它们时,您将遇到链接器错误: 错误LNK2019:未解析的外部符号…

    要解决此问题,我使用以下内容:

    复制两者之间的文字:

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

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

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

    OUTPUT_FORMAT(“elf64-x86-64”,“elf64-x86-64”,“elf64-x86-64”)

    ……..

      __start_my_array = .; .my_array : { *(.my_array) } __stop_my_array = .; 

    对的,这是可能的。 通常的技巧是将所有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 }; 

    您实际上可以使用单个宏来设置函数指针,执行函数声明,设置枚举以访问函数指针和用于错误消息的字符串,稍后您可以在switch()使用它。

     #define X_MACRO(OP)  OP(addi, int x, int y)  OP(divi, int x, int y)  OP(muli, int x, int y)  OP(subi, int x, int y) #define AS_FUNC_PTR(x,...) x, #define AS_FUNC(x,...) int x(__VA_ARGS__); #define AS_STRINGS(x,...) #x, #define AS_ENUMS(x,...) ENUM_##x, X_MACRO(AS_FUNC) typedef int (*foo_ptr_t)( int, int ); foo_ptr_t foo[] = { X_MACRO(AS_FUNC_PTR) }; char *foo_strings[] = { X_MACRO(AS_STRINGS) }; enum foo_enums { X_MACRO(AS_ENUMS) }; /** example switch() #define AS_CASE(x,...) ENUM_x : x(i,j);break; switch (my_foo_enum){ X_MACRO(AS_CASE) default: do_error(); } **/ 

      以上就是c/c++开发分享使用宏将项目附加到具有宏的数组中相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/544816.html

      (0)
      上一篇 2021年1月9日
      下一篇 2021年1月9日

      精彩推荐