【问题标题】:Accessing a struct field using an int or enum value使用 int 或 enum 值访问结构字段
【发布时间】:2019-10-11 11:02:57
【问题描述】:

我目前使用的日志系统使用标签值来识别它将存储的参数。我们使用的格式如下: 标签+时间+价值。

下一步是获取记录的消息并使用协议缓冲区将其发送到服务器以序列化数据。

protocol buffer .proto 文件,提供了一个结构体,所有字段对应于原始日志系统中的一个标签。

当我需要有效地读取标签并将值分配给协议缓冲区结构中的字段时,问题就出现了。本质上,我想例如接受标签 5 并能够在结构中找到字段 5 并写入值。

我知道这可以通过 switch case 来完成,但是我们使用了大约 50 个标签,所以我想尽可能避免使用这种解决方案。我附上一个示例结构来说明问题。

/* Struct definitions */
typedef struct _Profiles {
    int32_t param1;
    int32_t param2;
    int32_t param3;
    int32_t param4;
    int32_t param5;
    int16_t param6;
    int32_t param7;
    uint32_t param8;
    int32_t param9;
    int32_t param10;
    uint32_t param11;
    int32_t time;
/* @@protoc_insertion_point(struct:Profiles) */
} Profiles;

预期的结果是我可以存储如下记录的行: 5 1345643 1500(标签、时间、值)

到一个协议缓冲区结构:

profiles.param5 = 1500
profiles.time  = 1345643 

不需要 12 个 switch case(在这个例子中)。基本上,如何使用整数/枚举访问结构的第 5 个声明字段。

请记住,结构的每个字段都可能具有不同的类型。

【问题讨论】:

  • 为什么你有成员 param1 .. param10 而不是数组 int32_t param[10]?或者名称是说明性的。
  • 在这个问题中,它们确实是说明性的,并且可能具有不同的类型。

标签: c struct


【解决方案1】:

我的方法是使用指向每个字段的指针,如下所示。

int *ptr[11] = {&profiles.param1, &profiles.param2,  &profiles.param3,,,,,, &profiles.param11};

当消息到达时,我将使用ptr 更新该字段。

  *ptr[tag-1] = 1500; //tag-1 because ptr[4] points to profiles.param5

【讨论】:

  • 非常感谢@kiran 的快速响应。据我了解,指向的所有值都必须是整数。如果结构有浮点数、字符串和不同的类型,这将如何工作?我努力调整它以使其适用。也许我提供的示例结构不是最好的解释。
  • 您可以使用void * 而不是int *,并且在取消引用时确保将类型转换为实际类型。这仅在您知道要进行类型转换的类型时才有效。
【解决方案2】:

改进@kiran 之前的解决方案。

如果您有多种类型,那么您需要存储 void 指针。但是对于类型转换,您再次需要一个开关盒。

这可以通过两种方式避免。

  1. 将类型与数据一起存储。即,存储(tag, type, time, value)。然后你可以有一个有限的类型条件。

    void *ptr[11] = {&profiles.param1, &profiles.param2,  &profiles.param3,,,,,, &profiles.param11};
    
    switch (type)
    {
        case 0:
            *(char*)ptr[tag-1] = value;
            break;
        case 1:
            *(int*)ptr[tag-1] = value;
            break;
        ...
    }
    
  2. 或者你可以有一个存储值类型的映射

    void *ptr[11] = {&profiles.param1, &profiles.param2,  &profiles.param3,,,,,, &profiles.param11};
    char typearr[11] = {0,1,0,0....1};  // 0 for char, 1 for int etc
    
    type = typearr[tag-1];
    
    switch (type)
    {
       ...
    } 
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 2018-08-27
    • 2020-12-26
    • 2014-06-20
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多