首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多重__COUNTER__ C

多重__COUNTER__ C
EN

Stack Overflow用户
提问于 2016-11-09 10:45:52
回答 2查看 1K关注 0票数 0

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

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

hierarchy.h

代码语言:javascript
复制
#define HIERARCHY_DEFINE(NAME) int hierarchyId = __COUNTER__

event.h

代码语言:javascript
复制
#define EVENT_REGISTER(NAME) int eventId = __COUNTER__

main.c

代码语言:javascript
复制
#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;
}

这将打印出来:

代码语言:javascript
复制
events(0, 2) modules(1)

当我试图实现:

代码语言:javascript
复制
events(0, 1) modules(0)

我环顾四周,人们都说我不能独自创造一个计数器。看到了助推计数器,但这也不能达到我想要的效果。

有人知道我怎么处理这种情况吗?

谢谢!

编辑:

稍微改进一下我的代码实际上是什么样子

代码语言:javascript
复制
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");
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-09 11:28:24

你必须要么:

  • 在运行时分配ids,
  • 用手分配ids
  • 或者将所有事件和模块定义保存在一个地方。

假设您有a.cb.c,它们分别包含一些EventAEventB定义。由于它们是单独的编译单元,所以编译器无法将不重叠的is分配给它们。编译b.c时,它甚至不知道还有另一个a.c已经分配了id 1

对于第一个函数,有一个如下所示的RegisterEvent函数:

代码语言:javascript
复制
void RegisterEvent(Event* event){
  static int nextEventId = 0;
  event->eventId = nextEventId;
}

并为您需要的每一个Event调用它。

第二种是显而易见的,但很乏味,而且容易出错。

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

有你所有事件的X-列表:

代码语言:javascript
复制
#define EventList \
  Event(FirstEvent, "FirstEvent") \
  Event(Timer_1, "Timer 1 hZ") \
  ... 
  Event(Timer_5, "Timer 5 hZ")

现在,在标题中,您将声明所有事件(例如,events.h):

代码语言:javascript
复制
#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):

代码语言:javascript
复制
#include "events.h"

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

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

代码语言:javascript
复制
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" };

模块也是如此。

票数 1
EN

Stack Overflow用户

发布于 2016-11-09 10:54:27

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

definitions.inc

代码语言:javascript
复制
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

代码语言:javascript
复制
#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;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40505091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档