我在玩预处理器和c,试图实现我自己的事件和层次结构系统。不过,我正面临着一个问题。我试图静态地定义可以初始化的“模块”,以及一些预先静态定义的事件。对于这些事件,我使用的是计数器,它工作得很漂亮。但我不想混淆模块id和事件id的。
因此,我试图实现的一个简化版本是:
hierarchy.h
#define HIERARCHY_DEFINE(NAME) int hierarchyId = __COUNTER__event.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");发布于 2016-11-09 11:28:24
你必须要么:
假设您有a.c和b.c,它们分别包含一些EventA和EventB定义。由于它们是单独的编译单元,所以编译器无法将不重叠的is分配给它们。编译b.c时,它甚至不知道还有另一个a.c已经分配了id 1。
对于第一个函数,有一个如下所示的RegisterEvent函数:
void RegisterEvent(Event* event){
static int nextEventId = 0;
event->eventId = nextEventId;
}并为您需要的每一个Event调用它。
第二种是显而易见的,但很乏味,而且容易出错。
对于第三种解决方案,您可以使用X宏。
有你所有事件的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" };模块也是如此。
发布于 2016-11-09 10:54:27
除非您对标识符有其他要求,否则将执行下列操作:
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_REGISTERapp.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;
}https://stackoverflow.com/questions/40505091
复制相似问题