【问题标题】:C equivalent of C++ enum data for binary reading and manipulatingC 等效于 C++ 枚举数据,用于二进制读取和操作
【发布时间】:2020-11-02 17:24:39
【问题描述】:

尝试将一些 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 中不存在这类枚举。您需要使用显式的uint16_t 值。可能是typedef uint16_t GssipFlags,还有一堆#defines。
  • 只需删除: uint16_t。您可以将枚举分配给 uint16_t 变量
  • 为什么你需要数字文字类型为uint16_t
  • 您可以像在 C++ 中一样定义枚举常量,尽管它们的类型为int。但是枚举的类型是实现定义的,因此,如果您想在结构或其他任何内容中包含uint16_t 字段,则需要显式使用uint16_t。例如,struct foo { uint16_t Flags, MessageID, WarningMsgID; } = { ACK_MSG, RECEIVER_ID_MSG, SELF_TEST_OK }; 应该可以工作。
  • 如果您确实需要常量本身具有uint16_t 类型,您可以使用enum 定义它们,然后添加诸如#define SPARE0 ((uint16_t) SPARE0) 之类的宏。宏不会被递归替换,因此它只会扩展为 ((uint16_t) SPARE0),并且将具有所需的类型。

标签: c++ c enums binary


【解决方案1】:

您有一个标准选项和两个潜在选项,具体取决于您的编译器以及“我正在处理二进制数据并需要使用 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 问题,它们会根据您的实际问题提供不同的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2014-01-17
    • 2021-01-24
    • 2021-08-16
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多