我正在玩预处理器和c。试图实现我自己的事件和层次结构系统。 但是我遇到了问题。我试图静态定义我的"模块"可以初始化,以及一些事先也是静态定义的事件。对于我使用 COUNTER 这些非常有效的活动。但我不想混淆模块ID和事件ID。
这是我试图实现的简化版本:
hierarchy.h
project/folder
event.h
#define HIERARCHY_DEFINE(NAME) int hierarchyId = __COUNTER__
的main.c
#define EVENT_REGISTER(NAME) int eventId = __COUNTER__
这将打印出来:
#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)
答案 0 :(得分:3)
除非您对标识符有其他要求,否则将执行以下操作:
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
#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;
}
答案 1 :(得分:1)
您必须:
考虑您有a.c
和b.c
,它们分别包含一些EventA
和EventB
定义。由于它们是单独的编译单元,因此编译器无法为它们分配非重叠的ID。正在编译b.c
,它甚至不知道还有另一个a.c
已经分配了1
。
对于第一个,有一个RegisterEvent
函数,如下所示:
void RegisterEvent(Event* event){
static int nextEventId = 0;
event->eventId = nextEventId;
}
并为您需要的每个Event
拨打电话。
第二个是显而易见的,但是很乏味且容易出错。
对于第三种解决方案,您可以使用X macro。
拥有所有活动的X列表:
#define EventList \
Event(FirstEvent, "FirstEvent") \
Event(Timer_1, "Timer 1 hZ") \
...
Event(Timer_5, "Timer 5 hZ")
现在,在标题中,您将声明所有事件(例如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
在您的事件定义所在的单个编译单元中(例如,events.c
):
#include "events.h"
#define Event(name, desc) \
Event name = {.eventId = EventID ## name, .data = 0, .description = desc };
EventList
#undef Event
宏扩展后,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" };
模块也是如此。