在您对this answer的评论中,
我正在尝试将此结构复制到闪存 [内存芯片]。 Flash 读/写 API 传递一个字符串。 – Punit 2 小时前
你透露你有一个XY Problem - 你问的是如何实现你的解决方案,而不是如何解决你的问题。您并不是真的想将结构复制到缓冲区,而是想使用需要 char * 参数的 API 将结构中的数据写入 Flash。
其他人指出memcpy 会做你想做的事。但它们都涉及在 RAM 中为这个缓冲区分配内存。使用这些方法会奏效,但会浪费时间和内存。假设您的 Flash API 具有以下功能:
int WriteBlock(int address, char *data, int length);
并且您已将结构存储在名为 data_var 的变量中,您可以以与 memcpy 相同的方式使用您的 API:
int success = WriteBlock(my_address, (char *) &data_var, sizeof(struct data)
为了更清楚并避免强制转换,您可能希望将其包装在一个联合中:
union {
struct data{
int num1;
int num2;
int num3;
int num4;
};
char data_arr[sizeof(struct data)];
};
这将允许您使用更传统的语法来调用它。
请注意,如果您的结构不连续,这两种方法(和 memcpy!)都可能会失败。例如,也许您的结构如下所示:
struct data{
int num1;
char num2;
long num3;
short num4;
}
如果您使用的不是 8 位系统,那么这种结构很可能(取决于您的架构)包含间隙。
例如,假设 num1 是 0x12345678,num2 是 0x9A,num3 是 0xBCDEF0123456789A,num4 是 0xBCDE,那么您可能有以下任何一种情况(假设您的内存是零初始化的,并且为清楚起见是 big-endian):
/* 8 位 */
0x1234 5678 9ABC DEF0 1234 5678 9ABC DE00
/* 16 位 */
0x1234 5678 009A BCDE F012 3456 789A BCDE
/* 32 位 */
0x1234 5678 0000 0000 0000 009A BCDE F012 3456 789A 0000 0000 0000 BCDE
在这种情况下,您将不得不使用更丑陋的东西,例如以下函数:
int fillDataBuffer(struct data d, char *buffer, int len)
{
int i, j = 0;
for (i = sizeof(d.num1) - 1; i >= 0 && j < len; i--, j++) {
buffer[j] = (char) (d.num1 >> i);
}
for (i = sizeof(d.num2) - 1; i >= 0 && j < len; i--, j++) {
buffer[j] = (char) (d.num2 >> i);
}
for (i = sizeof(d.num3) - 1; i >= 0 && j < len; i--, j++) {
buffer[j] = (char) (d.num3 >> i);
}
for (i = sizeof(d.num4) - 1; i >= 0 && j < len; i--, j++) {
buffer[j] = (char) (d.num4 >> i);
}
if (j >= len) {
/* Error! The buffer wasn't big enough. */
return 0;
} else {
return 1;
}
}
或#pragma pack() 宏,但这可能会使使用该结构的计算变慢,并且您可能宁愿在要进行缓冲时打包它。