c - 将结构覆盖到任意缓冲区
问题描述
我是一名“新”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++。
我不在乎缓冲区是否“跑出”结构的末尾,代码结构会处理这个问题。
解决方案
首先解决您在此行的错误消息:
mp = (struct MessageTable) &buf;
在这里,您尝试将&buf
类型(char (*)[256]
即指向数组的指针)转换struct MessageTable
为非指针类型的 a。在大多数情况下,数组会衰减为指向第一个元素的指针,因此您不需要获取其地址,并且需要将其转换为指针类型:
mp = (struct MessageTable *)buf;
然而,另一个问题是:
- 结构可能不是您期望的大小
- bitfieds 的顺序可能不是你所期望的
- 如果缓冲区未正确对齐结构中的字段,则可能会产生错误。