首页 > 解决方案 > C 等效于 C++ 枚举数据,用于二进制读取和操作

问题描述

试图将一些 C++ 代码转换为 C,我正在处理二进制数据,需要使用与此等效的 C:

enum GssipFlags : uint16_t
    {
        SPARE0     = 1,
        SPARE1     = 2 * SPARE0,
        SPARE2     = 2 * SPARE1,
        SPARE3     = 2 * SPARE2,
        REQ_MSG    = 2 * SPARE3,
        DISCONNECT = 2 * REQ_MSG,
        CONNECT    = 2 * DISCONNECT,
        INVALID_DATA = 2 * CONNECT,
        CMD_REJECT = 2 * INVALID_DATA,
        HANDSHAKE  = 2 * CMD_REJECT,
        NAK_MSG    = 2 * HANDSHAKE,
        ACK_MSG    = 2 * NAK_MSG,
        ACK_REQ    = 2 * ACK_MSG,
        RESYNC     = 2 * ACK_REQ,
        MODE       = 2 * RESYNC,
        READY      = 2 * MODE
    };

    enum GssipMessageIDs : uint16_t
    {
        CCCCCCCC = 1,
        RECEIVER_ID_MSG = 2,
        BUFFER_BOX_STATUS_REQUEST_MSG = 3,
        SETUP_DATA_5031 = 4,
        WARNING_MSG = 5,
        TIME_TRANSFER = 6
    };

    enum GssipWarningMsgIDs : uint16_t
    {
        EXTERNAL_POWER_DISCONNECT = 17,
        SELF_TEST_OK = 8,
        AAAAA = 9,
        BBBBB = 10
    };

我试过的一切都没有奏效。我需要的主要方面是一切都是 uint16_t

标签: c++cenumsbinary

解决方案


您有一个标准选项和两个潜在选项,具体取决于您的编译器以及“我正在处理二进制数据并需要使用 C”的含义(内存使用情况?速度?等):

  • 这已经被评论了,使用具有您正在寻找的类型的结构:
typedef struct {
    uint16_t SPARE0;
    ...
} GssipFlags_t;

GssipFlags_t a = {
    .SPARE0=1
    ...
};

  • 如果您试图减小枚举的大小,请利用编译器(如果可用)并使用-fshort-enums.

分配给枚举类型的字节数仅与声明的可能值范围所需的字节数一样多。具体来说,枚举类型相当于有足够空间的最小整数类型。

  • __attribute__((packed)),以删除成员之间添加的填充(由于访问未对齐数据的成本,这可能会降低处理速度)。

  • 如果您不介意大小并且您唯一关心的是使用 C 编译器编译 C++11 代码(它可能产生与添加相同的输出-fshort-enums),只需执行以下操作:

enum GssipFlags {
    SPARE0     = 1
    ...
};

第 2、3 和 4 项没有明确创建具有uint16_t类型的成员,但如果这是 XY 问题,它们会根据您的实际问题提供不同的解决方案。


推荐阅读