在结构上使用memcpy时我遇到了一个问题。
考虑下面的结构
struct HEADER
{
unsigned int preamble;
unsigned char length;
unsigned char control;
unsigned int destination;
unsigned int source;
unsigned int crc;
}如果我使用memcpy将数据从接收缓冲区复制到此结构,则复制是正常的,但如果我将此结构重新声明为以下内容:
struct HEADER
{
unsigned int preamble;
unsigned char length;
struct CONTROL control;
unsigned int destination;
unsigned int source;
unsigned int crc;
}
struct CONTROL
{
unsigned dir : 1;
unsigned prm : 1;
unsigned fcb : 1;
unsigned fcb : 1;
unsigned function_code : 4;
}现在,如果我使用与以前相同的memcpy代码,则前两个变量(前同步码和长度)复制正常。控制完全混乱,最后三个变量被上移一位,也就是crc = 0,source = crc,destination = source...
ANyone对我有什么好的建议吗?
发布于 2013-10-09 18:01:23
当您在中间添加control时,您是否知道接收缓冲区中的格式是正确的?
无论如何,您的问题是位域在这里是错误的工具:您不能依赖于内存中的布局是特定的,至少不能依赖于您为序列化表单选择的完全相同的布局。
尝试直接将结构复制到外部存储或从外部存储复制结构几乎不是一个好主意;您需要适当的序列化。编译器可以在结构的字段之间添加填充和对齐,而使用位域会使情况变得更糟。不要这样做。
实现正确的序列化/反序列化函数:
unsigned char * header_serialize(unsigned char *put, const struct HEADER *h);
unsigned char * header_deserialize(unsigned char *get, struct HEADER *h);它遍历结构并读/写所需的字节数(可能针对每个字段):
static unsigned char * uint32_serialize(unsigned char *put, uint32_t x)
{
*put++ = (x >> 24) & 255;
*put++ = (x >> 16) & 255;
*put++ = (x >> 8) & 255;
*put++ = x & 255;
return put;
}
unsigned char * header_serialize(unsigned char *put, const struct HEADER *h)
{
const uint8_t ctrl_serialized = (h->control.dir << 7) |
(h->control.prm << 6) |
(h->control.fcb << 5) |
(h->control.function_code);
put = uint32_serialize(put, h->preamble);
*put++ = h->length;
*put++ = ctrl_serialized;
put = uint32_serialize(put, h->destination);
put = uint32_serialize(put, h->source);
put = uint32_serialize(put, h->crc);
return put;
}请注意,这需要明确表示序列化数据的字节顺序,这是您应该始终关注的事情(我使用的是big-endian)。它还显式地构建control字段的单个结构版本,假设使用的是结构版本。
还要注意,您的CONTROL声明中有一个拼写错误;fcb出现了两次。
发布于 2013-10-09 18:01:29
使用struct CONTROL control;而不是unsigned char control;会导致结构内部出现不同的对齐方式,因此用memcpy()填充结构会产生不同的结果。
发布于 2013-10-09 18:02:11
Memcpy将字节的值从source指向的位置直接复制到destination指向的内存块。
源指针和目标指针所指向的对象的底层类型与此函数无关;结果是数据的二进制副本。因此,如果有任何结构填充,那么你就会得到混乱的结果。
https://stackoverflow.com/questions/19268744
复制相似问题