我有这个问题,我不知道是否有所期待,这就是事情:
我正在尝试将文件中的字节加载到这样的结构中:
struct
{
char
char
char
char
unsigned int
}
但问题是当unsigned int被填充时,似乎在读取流中字节被交换,e.x。如果文件包含0x45080000,则unsigned int将为0x84500000,这是错误的。
如果我改变了BYTE [4]的unsigned int,这可以“解决”,但不是我想要的。这是我用来从文件中读取的代码:
fopen_s( &mFile, "myFile.ext", "rb" );
if( mFile == NULL ) print( " **** E R R O R ! **** " );
else
{
if( fread( &myStruct, sizeof( MY_Struct ), 1, myFile) != 1)
{
print( " **** E R R O R ! **** " );
return 0;
}
}
这是预期的行为还是我做错了什么?
此致
答案 0 :(得分:3)
正如您所发现的,便携式序列化可能会很痛苦。您需要以规范化格式单独序列化每个属性(网络字节顺序很常见),而不是编写和读取结构。然后,当您反序列化时,字节会正确返回。
答案 1 :(得分:1)
单独序列化/反序列化每个字段(符合标准)或......
使用特定于平台的选项:
#pragma pack(push,1)
struct foo {
// ...
};
#pragma pack(pop)
这将foo中的所有变量与1字节对齐对齐,因此它不适用于布尔值。
如果你打算跨平台,你将不得不测试它的地狱性和pragma支持的问题。
答案 2 :(得分:1)
只是为蛋糕添加一些结冰!
您还必须处理32位与64位问题。
一个非常好的包含文件是stdint.h(C99)。它定义了具有特定大小的类型,因此在切换字宽时可以减少问题。
答案 3 :(得分:0)
你可能需要考虑大/小端。 试试s.th.像这样:
#define BIG_ENDIAN
//#define LITTLE_ENDIAN
...
#ifdef BIG_ENDIAN
inline void writeMem32(uint8* buf, uint32 val)
{
buf[0] = static_cast<uint8>(val >> 24);
buf[1] = static_cast<uint8>(val >> 16);
buf[2] = static_cast<uint8>(val >> 8);
buf[3] = static_cast<uint8>(val >> 0);
}
inline uint32 readMem32(const uint8* buf)
{
return ( ((*(buf+0)) << 24) | ((*(buf+1)) << 16) | ((*(buf+2)) << 8) | (*(buf+3)) );
}
#endif // BIG_ENDIAN
如果你在小端,字节顺序当然是不同的:)