我正在从ARM micro的SD卡中读取值:
Res = f_read(&fil, (void*)buf, 6, &NumBytesRead);
其中fil
是指针,buf
是存储数据的缓冲区。
这就是问题所在:这是一个数组,但是我想将该数组的内容放在一个变量中。
举一个实际的例子:从文件中读取的6个字节是:
buf[0] = 0x1B
buf[1] = 0x26
buf[2] = 0xB3
buf[3] = 0x54
buf[4] = 0xA1
buf[5] = 0xCF
我想拥有:uint64_t data
等于0x1B26B354A1CF
。也就是说,数组的所有元素都以一个64位整数“串联”。
答案 0 :(得分:6)
无需键入修剪,您可以执行以下操作。
.d.ts
答案 1 :(得分:3)
使用并集,但要记住字节序。
union
{
uint8_t u8[8];
uint64_t u64;
}u64;
typedef联合 { uint8_t u8 [8]; uint64_t u64; } u64;
typedef enum
{
LITTLE_E,
BIG_E,
}ENDIANESS;
ENDIANESS checkEndianess(void)
{
ENDIANESS result = BIG_E;
u64 d64 = {.u64 = 0xff};
if(d64.u8[0]) result = LITTLE_E;
return result;
}
uint64_t arrayToU64(uint8_t *array, ENDIANESS e) // for the array BE
{
u64 d64;
if(e == LITTLE_E)
{
memmove(&d64, array, sizeof(d64.u64));
}
else
{
for(int index = sizeof(d64.u64) - 1; index >= 0; index--)
{
d64.u8[sizeof(d64.u64) - index - 1] = array[index];
}
}
return d64.u64;
}
int main()
{
uint8_t BIG_E_Array[] = {0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80};
ENDIANESS e;
printf("This system endianess: %s\n", (e = checkEndianess()) == BIG_E ? "BIG":"LITTLE");
printf("Punned uint64_t for our system 0x%lx\n", arrayToU64(BIG_E_Array, e));
printf("Punned uint64_t for the opposite endianess system 0x%lx\n", arrayToU64(BIG_E_Array, e == BIG_E ? LITTLE_E : BIG_E));
return 0;
}
答案 2 :(得分:0)
要照顾的事情在这里:
通过使用以下两个marcos将以网络字节顺序(Big Endian)进入的字节存储到主机字节顺序的64位整数中,可以解决问题1。
/* below defines of htonll() and ntohll() are taken from this answer:
https://stackoverflow.com/a/28592202/694576
*/
#if __BIG_ENDIAN__
# define htonll(x) (x)
# define ntohll(x) (x)
#else
# define htonll(x) ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# define ntohll(x) ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
#endif
问题2可以通过多种方式解决:
扩展您的方法
#define BUFFER_SIZE (6)
...
assert(BUFFER_SIZE <= sizeof (uint64_t));
uint8_t buffer[BUFFER_SIZE];
FILE * pf = ...; /* open file here */
/* test if file has been opened successfully here */
... result = f_read(pf, buffer, BUFFER_SIZE, ...);
/* test result for success */
uint64_t number = 0;
memset(&number, buffer, BUFFER_SIZE)
number = ntohll(number);
通过并集使用“ Type Punning ”
union buffer_wrapper
{
uint8_t u8[sizeof (uint64_t)];
uint64_t u64;
}
代替
uint8_t buffer[BUFFER_SIZE];
使用
union buffer_wrapper buffer;
而不是
memcpy(&number, buffer, BUFFER_SIZE)
number = ntohll(number)
使用
number = ntohll(buffer.u64)