gpt4 book ai didi

c++ - 文件解析中奇怪的对象序列化问题

转载 作者:行者123 更新时间:2023-11-28 08:28:28 25 4
gpt4 key购买 nike

我在对象序列化方面遇到了一个奇怪的问题。在文件文档中它声明如下

The lead in starts with a 4-byte tag that identifies a TDMS segment ("TDSm"). The next four bytes are used as a bit mask in order to indicate what kind of data the segment contains. This bit mask is referred to as ToC (Table of Contents). Any combination of the following flags can be encoded in the ToC: The next four bytes contain a version number (32-bit unsigned integer), which specifies the oldest TDMS revision a segment complies with. At the time of this writing, the version number is 4713. The only previous version of TDMS has number 4712. The next eight bytes (64-bit unsigned integer) describe the length of the remaining segment (overall length of the segment minus length of the lead in). If further segments are appended to the file, this number can be used to locate the starting point of the following segment. If an application encountered a severe problem while writing to a TDMS file (crash, power outage), all bytes of this integer can be 0xFF. This can only happen to the last segment in a file. The last eight bytes (64-bit unsigned integer) describe the overall length of the meta information in the segment. This information is used for random access to the raw data. If the segment contains no meta data at all (properties, index information, object list), this value will be 0.

所以我实现为

class TDMsLEADIN {
public:
char Signature[4]; //TDSm
__int32 Toc;
unsigned __int32 vernum;
unsigned __int64 nextSegmentOff;
unsigned __int64 rawDataOff;
};
fread(&leadin,sizeof(TDMsLEADIN),1,f);

然后我得到了预期的 signature="TDsm", TOc=6, vernum=4712。 nextSegmentOff=833223655424,rawDataOff=8589934592 但预计 nextSegmentOff 和 rawDataOff=194

然后我将类(class)分成两部分,分别阅读两部分

class TDMsLEADIN {
public:
char Signature[4]; //TDSm
__int32 Toc;
unsigned __int32 vernum;

};
class TDMsLeadINend{
public:
unsigned __int64 nextSegmentOff;
unsigned __int64 rawDataOff;
};
fread(&leadin,sizeof(TDMsLEADIN),1,f);
fread(&leadin2,sizeof(TDMsLeadINend),1,f);

然后我得到了预期的 nextSegmentOff ,rawDataOff=194。我的问题是原始代码有什么问题?为什么当我把它分成两部分时它会起作用?我尝试使用 unsigned long long 而不是 unsigned __int64,但结果仍然相同。这很奇怪。

谢谢

最佳答案

您似乎只是直接在结构中读写二进制数据。

通常编译器会为了性能对齐结构数据,所以当它是单个结构时,在 vernumnextSegmentOff 之间有一个隐藏的 32 位填充以对齐 nextSegmentOff 。当它被分成两个结构时,就没有这样的额外填充,您正在将四个字节的填充和四个字节的实际数据读入 nextSegmentOff

您可以通过将 sizeof(TDMsLEADIN [second version]) + sizeof(TDMsLeadINend)sizeof(TDMsLEADIN [first version]) 进行比较来测试这一点

序列化数据的标准方法是单独序列化每个基础部分,而不是依赖于类或结构的布局,因为编译器可能会更改布局,恕不另行通知。

关于c++ - 文件解析中奇怪的对象序列化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3150844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com