简体   繁体   English

多个__COUNTER__ C

[英]Multiple __COUNTER__ C

I'm playing around with the preprocessor and c. 我在玩预处理器和c。 Trying to implement my own event and hierarchy system. 尝试实现我自己的事件和层次结构系统。 However I'm facing a problem. 但是我面临一个问题。 I'm trying to statically define my "modules" which can be initialized, and some events which also are statically defined in advance. 我试图静态定义可以初始化的“模块”,以及一些事先也静态定义的事件。 For the events I'm using COUNTER which works beautiful. 对于事件,我使用的是COUNTER ,效果很好。 But I don't want to mix up module id's and event id's. 但是我不想混淆模块ID和事件ID。

So a simplified version of what I'm trying to achieve: 因此,我尝试实现的简化版本:

hierarchy.h hierarchy.h

#define HIERARCHY_DEFINE(NAME) int hierarchyId = __COUNTER__

event.h event.h

#define EVENT_REGISTER(NAME) int eventId = __COUNTER__

main.c 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;
}

This will print out: 这将打印出:

events(0, 2) modules(1)

When I'm trying to achieve: 当我尝试实现以下目标时:

events(0, 1) modules(0)

I've looked around and people saying I can't create a counter on my own. 我环顾四周,有人说我不能自己创建计数器。 And seen the boost counter, but that doesn't achieve what I want either. 看到了升压计数器,但这也没有实现我想要的。

Does anybody have an idea how I could handle this situation? 有人知道我该如何处理这种情况吗?

Thanks! 谢谢!

Edit: 编辑:

slight adition of what my code actually looks like 我的代码实际上看起来像什么

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");

Unless you have additional requirements for the identifiers, the following will do: 除非您对标识符有其他要求,否则将执行以下操作:

definitions.inc definitions.inc

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

app.c app.c

#define EVENT_REGISTER(a, d) a,
#define MODULE_REGISTER(a)
enum events {
#include "definitions.inc"
};

#define EVENT_REGISTER(a, d)
#define MODULE_REGISTER(a) a,
enum modules {
#include "definitions.inc"
};

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

#define MODULE_REGISTER(a)
#define EVENT_REGISTER(a, d) static struct Event Event_##a = { .event_id = a, \
    .data = NULL, \
    .description = d \
};
#include "definitions.inc"


int main (int argc, char **argv)
{
    printf("events(%d, %d) modules(%d)\n", Timer_10, Timer_5, Module_SSH);

    return EXIT_SUCCESS;
}

You must either: 您必须:

  • assign ids at runtime, 在运行时分配ID,
  • assign ids by hands 手动分配ID
  • or keep all events and modules definitions in one place. 或将所有事件和模块定义放在一个位置。

Consider that you have ac and bc , and they contains some EventA and EventB definitions respectively. 考虑您具有acbc ,它们分别包含一些EventAEventB定义。 As they are separate compilation units, there is no way compiler can assign non-overlapping ids to them. 由于它们是单独的编译单元,因此编译器无法为它们分配不重叠的ID。 Compiling bc , it doesn't even know there is another ac where id 1 is already assigned. 编译bc ,它甚至不知道还有另一个已经分配了id 1 ac

For the first one, have a RegisterEvent function like so: 对于第一个,具有一个RegisterEvent函数,如下所示:

void RegisterEvent(Event* event){
  static int nextEventId = 0;
  event->eventId = nextEventId;
}

And call it for every Event you need. 并为您需要的每个Event调用它。

Second one is obvious, but tedious and error prone. 第二个是显而易见的,但乏味且容易出错。

For the third solution, you can use an X macro . 对于第三个解决方案,可以使用X宏

Have a X-list of all your events: 列出所有事件的清单:

#define EventList \
  Event(FirstEvent, "FirstEvent") \
  Event(Timer_1, "Timer 1 hZ") \
  ... 
  Event(Timer_5, "Timer 5 hZ")

Now, in a header there you are going to declare all your events (say, events.h ): 现在,在标头中,您将声明所有事件(例如, events.h ):

#define Event(name, desc) EventID ## name,
enum EventID{
 EventIDZero = 0,
 EventList 
 EventIDCount
};
#undef Event

#define Event(name, desc) \
  extern Event name;
EventList
#undef Event

And in a single compilation unit where your event definitions will reside (say, events.c ): 并且在事件定义将驻留的单个编译单元中(例如, events.c ):

#include "events.h"

#define Event(name, desc) \
  Event name = {.eventId = EventID ## name, .data = 0, .description = desc };
EventList
#undef Event

After macro expansion, events.c looks like (slightly edited for readability): 宏扩展后, events.c看起来像(为便于阅读而略作编辑):

enum EventID{
 EventIDZero = 0,
 EventIDFirstEvent, EventIDTimer_1, EventIDTimer_5,
 EventIDCount
};

extern Event FirstEvent; 
extern Event Timer_1; 
extern Event Timer_5;

Event FirstEvent = {.eventId = EventIDFirstEvent, .data = 0, .description = "FirstEvent" }; 
Event Timer_1 = {.eventId = EventIDTimer_1, .data = 0, .description = "Timer 1 hZ" }; 
Event Timer_5 = {.eventId = EventIDTimer_5, .data = 0, .description = "Timer 5 hZ" };

Same thing goes for modules. 模块也一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM