首页 > 解决方案 > 将结构覆盖到任意缓冲区

问题描述

我是一名“新”C 程序员,但也是一名老汇编程序员,几天来一直在寻找答案。

我正在尝试使用 C struct 构造解析消息中的多个字段(这是一个带有嵌入式 RTU modbus 数据包的 LORA 收音机)。

我有这个示例代码显示了我的问题:

#include <stdio.h>
#include <stdint.h>

struct MessageTable{
    uint8_t msg_id;
    uint8_t from;
    uint8_t to;
    unsigned flags1 : 1;
    unsigned retransmitted : 1;
    unsigned hops : 4;
    union {
        unsigned long millisecs;
        unsigned char bytes[sizeof(unsigned long)];
    } ms;
};


struct MessageTable message, *mp;
struct MessageTable message_table[8] = {0};
char buf[256];

void main(void) {
    int i;
    for (i=0; i<255; i++)
        buf[i] = i;

    mp = (struct MessageTable) &buf;
    printf("To: %u, From: %u", mp->to, mp->from);
}

当我尝试编译时,我得到:

question.c: In function ‘main’:
question.c:27:18: error: conversion to non-scalar type requested
   27 |     mp = (struct MessageTable) &buf;
      |                  ^~~~~~~~~~~~

我正在尝试做的是,在缓冲区空间中的某个任意位置覆盖结构,以便命名访问不同的字段,而不是使用硬编码的偏移量(IEto=buf[2];retransmitted = buf[3]&02x;

什么是干净,可读,适当的方法来做到这一点?

注意:在不同的 buf 位置(LORA 路由、Modbus Send、Modbus Rx、Modbus err 等)会有多个结构,这是直接的 C,而不是 C++。

我不在乎缓冲区是否“跑出”结构的末尾,代码结构会处理这个问题。

标签: cdata-structuresstruct

解决方案


首先解决您在此行的错误消息:

mp = (struct MessageTable) &buf;

在这里,您尝试将&buf类型(char (*)[256]即指向数组的指针)转换struct MessageTable为非指针类型的 a。在大多数情况下,数组会衰减为指向第一个元素的指针,因此您不需要获取其地址,并且需要将其转换为指针类型:

mp = (struct MessageTable *)buf;

然而,另一个问题是:

  • 结构可能不是您期望的大小
  • bitfieds 的顺序可能不是你所期望的
  • 如果缓冲区未正确对齐结构中的字段,则可能会产生错误。

推荐阅读