clq

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

http://blog.csdn.net/itlionwoo/article/details/659459

FILETIME结构是一个64位值,它分成了两个部分: 

typedef struct _FILETIME {
  DWORD dwLowDateTime;
  DWORD dwHighDateTime;
} FILETIME, *PFILETIME;

你可能会被迷惑,就把整个FILETIME结构作为一个__int64直接进行存取。事实上,它的内存分布同一个64位整数完成相同。下面是个例子: 

pi = (__int64*)&ft; // 错误

 

(*pi) += (__int64)num*datepart; //错误

为什么我们要说这是一个错误?

忽略了字节对齐问题。

FILETIME 是由两个DWORD组成的结构,它只需要4个字节对齐,那么这就足够把每一个DWORD对齐到一个有效的DWORD边界。不需要把第一个DWORD去对齐到8个字节。而且事实上,你可能已经使用了一个结构,而这个结构中却没有如此对齐:WIN32_FIND_DATA结构.

typedef struct _WIN32_FIND_DATA {
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD nFileSizeHigh;
    DWORD nFileSizeLow;
    DWORD dwReserved0;
    DWORD dwReserved1;
    TCHAR  cFileName[ MAX_PATH ];
    TCHAR  cAlternateFileName[ 14 ];
} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;

通过分析,这三个FILETIME结构出现在WIN32_FIND_DATA结构开头的第4,12和第20个字节,他们已经被dwFileAttributes成员失去了8个字节对齐特性。Observe that the three FILETIME structures appear at offsets 4, 12, and 20 from the beginning of the structure. They have been thrown off 8-byte alignment by the dwFileAttributes member.

强制转换FILETIME到__int64会(在WIN32_FIND_DATA 中会)得到一个没有字节对齐指针。在需要字节对齐的框架上存取一个没有字节对齐指针会引起一个STATUS_DATATYPE_MISALIGNMENT 异常。 

就算你的平台能够自动修正这个对齐问题,你仍然会引起问题。思考:为什么LARGE_INTEGER 和 ULARGE_INTEGER结构没有这个问题?

--------------------------------------------------

那转换侩如何呢?

http://stackoverflow.com/questions/1566645/filetime-to-int64

说了一个错误的例子,我想是不是那个直接移位造成的? 因为要转成 int64 后才不会溢出嘛? 是这个道理吗,有空的网友可以试一下,我没试.

--------------------------------------------------

I don't think you're suppose to: "Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows."

Source.

If you really wanted it would be something like:

__int64 to_int64(FILETIME ft)
{
   
returnstatic_cast<__int64>(ft.dwHighDateTime)<<32| ft.dwLowDateTime;
}

FILETIME ft
=// ...
__int64 t
= to_int64(ft);

But something like:

FILETIME ft =// ...
__int64 t
=*reinterpet_cast<__int64*>(&ft);

Is bad.

有人说要这样

Try

(__int64(filetime.dwHighDateTime)<<32)| __int64(filetime.dwLowDateTime)
--------------------------------------------------
我的恶心点,是这样:
 
unsigned __int64 t;
                t = sr.FindData.ftLastWriteTime.dwHighDateTime;
                t = t << 32;
                t = t + sr.FindData.ftLastWriteTime.dwLowDateTime;
posted on 2011-12-01 20:17  clq  阅读(990)  评论(0编辑  收藏  举报