为什么不能将FILETIME看做__int64

为什么不能将FILETIME看做__int64

作者:BlogUpdater |  时间:2021-09-22 |  浏览:836 |  评论已关闭 条评论

我们先来看看FILETIME这个结构体,它通过组合两个DWORD来表示了一个64位的整数值。

你可能想将这个FILETIME结构体看做一个整体,然后将它们看做一个__int64结构来进行访问。
毕竟,这两个类型的内存布局都是一样的,下面是一些开发者写的代码,我们来看看:

上面的代码有什么错呢?
你答对啦:对齐。

因为这个FILETIME结构体包含两个DWORD部分,所以它只需要4个字节的对齐,因为将每个DWORD值对齐到一个有效的DWORD边界只需要4个字节对齐就够了。在第一个DWORD处我们并不需要对齐,因为它已经在一个8字节的边界了。而事实上,你可能已经用过了一个和FILETIME对齐方式不同的的结构体:WIN32_FIND_DATA,其定义如下图所示:

请注意,在上面的结构体定义中,有3个FILETIME结构体成员,分别定义在结构体起始地址的第4,第12和第20字节的偏移处。它们通过dwFileAttributes这个成员实现了8个字节的对齐。

将一个FILETIME转换为__int64会导致产生一个未对齐的指针。如果在一些要求对齐的处理器架构的系统上,程序代码访问了这个为对齐指针,会导致STATUS_DATATYPE_MISALIGNMENT异常。

即便你在一个不那么要求对齐的系统上执行这个转换,你还是会碰到一些其他的问题,我后面会在一些文章中详细解说。

课后练习题
为什么LARGE_INTEGER和ULARGE_INTEGER这两个结构体不受影响?

总结
以前在查看代码的时候,经常会在结构体定义中看到某些保留的字段,一开始还以为故作高深,后来懂了原理之后,才发现:小丑原来是我。
总之,我是长见识了。

最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Why can’t you treat a FILETIME as an __int64?》

最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。

标签:

评论已关闭。