尝试将结构成员复制到c中的字节数组
我试图将包含整数、字符和字符数组混合的结构的成员复制到字节数组中以发送到串行线。 到目前为止,
struct msg_on_send
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};
void switch_output_on()
{
int member;
struct msg_on_send SendMsg_on[sizeof member] =
{
};
unsigned char buffer [ sizeof SendMsg_on[0] ];
showbytes(buffer, serialize(buffer, SendMsg_on));
}
/***************************************************************************
* Function: ArrayBuild *
* Purpose: Uses memcopy to transfer the struct members sequentially *
* into an array of char *
* Arguments: *
* Returns: size_t i = a count of the number of bytes in the array *
***************************************************************************/
size_t ArrayBuild(unsigned char *dst, const struct msg_on_send *object)
{
size_t i = 0;
memcpy(&dst[i], &object->descriptor_msg, sizeof object->descriptor_msg);
i += sizeof object->descriptor_msg;
memcpy(&dst[i], &object->address, sizeof object->address);
i += sizeof object->address;
memcpy(&dst[i], &object->space, sizeof object->space);
i += sizeof object->space;
memcpy(&dst[i], &object->cmdmsg, sizeof object->cmdmsg);
i += sizeof object->cmdmsg;
memcpy(&dst[i], &object->CR, sizeof object->CR);
i += sizeof object->CR;
memcpy(&dst[i], &object->LF, sizeof object->LF);
i += sizeof object->LF;
return i;
}
/***********************************************************************
* Function: USARTWrite *
* Purpose: Writes the array data to the USART data register *
* Arguments: void *object = struct member *
* size_t size = size of array remaining *
* Returns: None *
***********************************************************************/
void USARTWrite(const void *object, size_t size)
{
const unsigned char *byte;
for ( byte = object; size--; ++byte )
{
printf("%02X", *byte);
}
putchar('\n');
}
当我获得这段代码时,我并不完全理解它是如何工作的。 我可以看到 memcpy 获取结构体的每个元素并将其放入由“i”变量索引的串行流中,但我不知道 USARTWrite 函数如何将其打包成字符串,或者如何使用我的结构初始化。
抱歉,这篇文章有点长,但我刚刚开始这个编程百灵,并试图理解这个概念。
谢谢 戴夫
编辑:
哇,很快就有很多好的答案 - 谢谢大家。
slaz:这对我来说似乎是合乎逻辑的,我并没有真正考虑过这种方法,因为我还没有真正了解指针,但我开始看到它们是 C 的重要组成部分,所以我会适时地看看。
这行代码将数据发送到我的 UART,我将用什么替换包含消息内容的数组? 似乎我在这里缺少一个逻辑步骤,其中有一个变量告诉我我的结构从哪里开始以及它有多大,但没有要发送的数组
USART_SendData(USART1, message_on_contents[array_count]);
Harper Shelby:谢谢您的描述,它使我的头脑更加清晰。
戴夫
I am attempting to copy the members of a struct containing a mixture of ints, char's and arrays of chars into a byte array to send to a serial line. So far I have
struct msg_on_send
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};
void switch_output_on()
{
int member;
struct msg_on_send SendMsg_on[sizeof member] =
{
};
unsigned char buffer [ sizeof SendMsg_on[0] ];
showbytes(buffer, serialize(buffer, SendMsg_on));
}
/***************************************************************************
* Function: ArrayBuild *
* Purpose: Uses memcopy to transfer the struct members sequentially *
* into an array of char *
* Arguments: *
* Returns: size_t i = a count of the number of bytes in the array *
***************************************************************************/
size_t ArrayBuild(unsigned char *dst, const struct msg_on_send *object)
{
size_t i = 0;
memcpy(&dst[i], &object->descriptor_msg, sizeof object->descriptor_msg);
i += sizeof object->descriptor_msg;
memcpy(&dst[i], &object->address, sizeof object->address);
i += sizeof object->address;
memcpy(&dst[i], &object->space, sizeof object->space);
i += sizeof object->space;
memcpy(&dst[i], &object->cmdmsg, sizeof object->cmdmsg);
i += sizeof object->cmdmsg;
memcpy(&dst[i], &object->CR, sizeof object->CR);
i += sizeof object->CR;
memcpy(&dst[i], &object->LF, sizeof object->LF);
i += sizeof object->LF;
return i;
}
/***********************************************************************
* Function: USARTWrite *
* Purpose: Writes the array data to the USART data register *
* Arguments: void *object = struct member *
* size_t size = size of array remaining *
* Returns: None *
***********************************************************************/
void USARTWrite(const void *object, size_t size)
{
const unsigned char *byte;
for ( byte = object; size--; ++byte )
{
printf("%02X", *byte);
}
putchar('\n');
}
As I obtained this code, I don't fully understand how it works. I can see that the memcpy takes each element of the struct and makes it into a serial stream indexed by the 'i' variable, but I don't know how the USARTWrite function packetises this into a string, or how to load the array with my struct initialisation.
Sorry this post is a bit long, but I'm just starting this programming lark, and trying to get my head around this concept.
Thanks
Dave
EDIT:
wow, many good answers quickly - thanks guys.
slaz: That seems logical to me, I hadn't really thought about that approach as I haven't really got my head around pointers yet, but I am beginning to see that they are an essential part of C, so I duly will have a look.
This line of code sends the data to my UART, what would I replace the array containing the message contents with? It seems like I am missing a logical step here where I have a variable telling me where my structure starts and how big it is, but no array to send
USART_SendData(USART1, message_on_contents[array_count]);
Harper Shelby: Thank you for that description, it makes it much clearer in my mind.
rgds
Dave
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
抱歉,直到现在才看到你的评论。
下面的代码在 Linux 上编译得很好,所以我希望它对你有用。
printf() 以十六进制打印,每个字节将得到 2 个字符。
我希望这有帮助。
~
~
Sorry, I didn't see your comment until just now.
The code below compiles on Linux just fine, so I hope it works for you.
printf() is printing in hex, you will get 2 characters for each byte.
I hope this helps.
~
~
您不必实际将结构复制到字节数组中。
您可以选择这样做:
指针的力量! :)
You don't have to actually copy the struct into an array of bytes.
You could optionally do this:
The power of pointers! :)
完整的完整示例。 完美运作。 在 X-CODE 9 Objective-C
输出下测试:
Full complete example. Perfectly works. Tested under X-CODE 9 Objective-C
Output:
这相当简单:
1. ArrayBuild 采用指向 msg_on_send 结构的指针,对于其中的每个成员,使用 memcpy 将字节复制到像这样传入的 char 数组中 -
USARTWrite 只是给出一个 char 数组和一个大小 - 它抓取每个 char依次使用 printf() 将其作为十六进制值打印到屏幕上。
“魔力”在于 ArrayBuild - memcpy 执行从源到目标的字节字面复制,无需翻译。 假设 4 字节整数,由该函数构建的数组将如下所示:
我假设在“真实”应用程序中, printf() 调用将替换为对串行端口写入的调用。
It's fairly straightforward:
1. ArrayBuild takes a pointer to a msg_on_send structure, and for each member in there, uses memcpy to copy the bytes into a char array that was passed in like so -
USARTWrite is just given a char array and a size - it grabs each char in turn and prints it to the screen as a hex value with printf().
The 'magic' is in the ArrayBuild - memcpy does a literal copy of bytes from source to destination, with no translation. Assuming 4-byte ints, the array built by the function will look like so:
I'd assume that in the 'real' application, the printf() call would be replaced by a call to a serial port write.
如果我想将结构视为字节数组,我通常使用联合将结构与字节数组组合起来。 例如:
If I want to treat a structure as an array of bytes I typically use a union to combined the structure with a byte array. For example:
这里的 struct 只是字节数组,它不包含指向它的指针。
成员到成员的复制很可能是为了处理对齐问题,因为
(char*) &address
可能会大于((char*) &descriptor_msg) + 5< /代码>。
USARTWrite
将结构体字节的HEX
代码发送到stdout
,但放弃对齐。 使用不同的对齐策略编译此代码将导致不同的输出。将结构声明包含在
#pragma pack(push, n)
和#pragma pack(pop)
中以强制对齐,然后只需逐字节复制结构即可。Your
struct
here is just array of bytes, it contains no pointers that point out of it.Member-to-member copy is most likely performed to cope with alignment, as
(char*) &address
will likely be greater than((char*) &descriptor_msg) + 5
.USARTWrite
sendsHEX
codes of the bytes of your struct tostdout
, but discards alignment. Compiling this code with different alignment strategies will lead to different outputs.Enclose your structure declaration into
#pragma pack(push, n)
and#pragma pack(pop)
to force alignment, and just copy your structure byte-to-byte.一个好的解决方案:
A good solution: