C 多重计数器

C 多重计数器,c,macros,c-preprocessor,counter,C,Macros,C Preprocessor,Counter,我在玩预处理器和c。尝试实现我自己的事件和层次结构系统。 然而,我面临一个问题。我试图静态地定义可以初始化的“模块”,以及一些预先静态定义的事件。对于我正在使用的事件,计数器,它工作得很漂亮。但我不想混淆模块id和事件id 因此,我试图实现的一个简化版本: events(0, 1) modules(0) 层次结构.h #define HIERARCHY_DEFINE(NAME) int hierarchyId = __COUNTER__ 事件h #define EVENT_REGISTER(

我在玩预处理器和c。尝试实现我自己的事件和层次结构系统。 然而,我面临一个问题。我试图静态地定义可以初始化的“模块”,以及一些预先静态定义的事件。对于我正在使用的事件,计数器,它工作得很漂亮。但我不想混淆模块id和事件id

因此,我试图实现的一个简化版本:

events(0, 1) modules(0)
层次结构.h

#define HIERARCHY_DEFINE(NAME) int hierarchyId = __COUNTER__
事件h

#define EVENT_REGISTER(NAME) int eventId = __COUNTER__
main.c

#include "event.h"
#include "hierarchy.h"

EVENT_REGISTER(EventOne);
HIERARCHY_DEFINE(ModuleOne);
EVENT_REGISTER(EventTwo);

int main(void){
    printf("events(%d, %d) modules(%d)\n",EventOne,EventTwo,ModuleOne);
    return 1;
}
这将打印出:

events(0, 2) modules(1)
当我试图实现以下目标时:

events(0, 1) modules(0)
我环顾四周,有人说我不能自己创建计数器。看到了加速计数器,但也没有达到我想要的

有人知道我如何处理这种情况吗

谢谢

编辑:

我的代码实际上看起来有点像

struct Event{
    uint8_t eventId;
    uint8_t * data;
    const char * description;
};

#define EVENT_REGISTER(eventName, desc)\
static Event eventName = {.eventId = __COUNTER__, .data = 0, .description = desc }




EVENT_REGISTER(Timer_5, "Timer 5 hZ");

除非您对标识符有其他要求,否则可以执行以下操作:

定义公司

EVENT_REGISTER(Timer_5, "Timer 5 Hz")
EVENT_REGISTER(Timer_10, "Timer 10 Hz")
MODULE_REGISTER(Module_SSH)
MODULE_REGISTER(Module_NCO)
#undef EVENT_REGISTER
#undef MODULE_REGISTER
附录c


除非您对标识符有其他要求,否则可以执行以下操作:

定义公司

EVENT_REGISTER(Timer_5, "Timer 5 Hz")
EVENT_REGISTER(Timer_10, "Timer 10 Hz")
MODULE_REGISTER(Module_SSH)
MODULE_REGISTER(Module_NCO)
#undef EVENT_REGISTER
#undef MODULE_REGISTER
附录c

您必须:

  • 在运行时分配ID
  • 手工分配身份证
  • 或者将所有事件和模块定义保存在一个位置
假设您有
a.c
b.c
,它们分别包含一些
EventA
EventB
定义。由于它们是独立的编译单元,编译器无法为它们分配不重叠的ID。编译
b.c
,它甚至不知道还有另一个
a.c
已经分配了id
1

对于第一个,使用如下函数的
RegisterEvent

void RegisterEvent(Event* event){
  static int nextEventId = 0;
  event->eventId = nextEventId;
}
并为您需要的每个
事件调用它

第二个是显而易见的,但繁琐且容易出错

对于第三种解决方案,可以使用

列出所有活动的X列表:

#define EventList \
  Event(FirstEvent, "FirstEvent") \
  Event(Timer_1, "Timer 1 hZ") \
  ... 
  Event(Timer_5, "Timer 5 hZ")
现在,在标题中,您将声明所有事件(例如,
events.h
):

在事件定义将驻留的单个编译单元中(例如,
events.c
):

宏展开后,
events.c
看起来像(为了可读性稍微编辑):

模块也是如此。

您必须:

  • 在运行时分配ID
  • 手工分配身份证
  • 或者将所有事件和模块定义保存在一个位置
假设您有
a.c
b.c
,它们分别包含一些
EventA
EventB
定义。由于它们是独立的编译单元,编译器无法为它们分配不重叠的ID。编译
b.c
,它甚至不知道还有另一个
a.c
已经分配了id
1

对于第一个,使用如下函数的
RegisterEvent

void RegisterEvent(Event* event){
  static int nextEventId = 0;
  event->eventId = nextEventId;
}
并为您需要的每个
事件调用它

第二个是显而易见的,但繁琐且容易出错

对于第三种解决方案,可以使用

列出所有活动的X列表:

#define EventList \
  Event(FirstEvent, "FirstEvent") \
  Event(Timer_1, "Timer 1 hZ") \
  ... 
  Event(Timer_5, "Timer 5 hZ")
现在,在标题中,您将声明所有事件(例如,
events.h
):

在事件定义将驻留的单个编译单元中(例如,
events.c
):

宏展开后,
events.c
看起来像(为了可读性稍微编辑):



模块也是如此。

如果ID是静态定义的,那么它们可以进入
枚举,对吗?那么您需要一个事件计数器,一个模块计数器,这两个计数器应该是分开的?那么,为什么不在宏中使用初始化为零并递增的两个变量呢?例如,
inteventid=eventIdCounter++他们可以,是的,但我喜欢尽可能轻松地注册事件。现在只有一行就足够了。我不想每次添加、删除或更改事件时都要更改枚举对不起,我遗漏了一些细节。我正在使用结构来保存信息。我需要常数来初始化它。编译器限制:(.所以我不能使用两个变量。我认为有人应该提到你正在尝试使用,这总是一个坏主意,甚至不起教育作用。如果ID是静态定义的,它们可以进入
枚举,对吗?所以你想要一个计数器用于事件,一个计数器用于模块,而这两个计数器应该是分开的?那为什么不只是使用两个变量,初始化为零并在宏中递增?例如,
int eventId=eventIdCounter++;
它们可以,是的,但我喜欢尽可能轻松地注册事件。现在只有一行就足够了。我不想在添加、删除或更改事件时一直更改枚举对不起,我遗漏了some详细信息。我正在使用结构来保存信息。我需要常量来初始化该信息。编译器限制:(.所以我不能使用两个变量。我想应该有人提到你正在尝试,这总是一个坏主意,甚至不起教育作用。那会起作用,是的,但现在我需要维护两个枚举列表。你指的是什么样的维护?嗯,我必须在某个地方注册事件,我必须添加它o枚举你必须在某个时间点上进行键入,你不能逃避。查看编辑。这会起作用,是的,但现在我需要维护两个枚举列表。你指的是什么样的维护?嗯,我必须在某个地方注册事件,我必须将其添加到枚举。你必须在某个时间点进行键入,你是吗e不能逃避。看看编辑。谢谢你的X宏!这是我希望通过这样做了解的东西。虽然在这种情况下这可能不是最好的方法。谢谢你的X宏!这是我希望通过这样做了解的东西。尽管