【问题标题】:OVERLAPPED STRUCTURES and LARGE_INTEGER重叠的结构和 LARGE_INTEGER
【发布时间】:2015-11-10 05:36:35
【问题描述】:

我完成了 Windows 系统编程中的练习,但我并没有完全理解 LARGE_INTEGER 和 OVERLAPPED 结构。例如,我在 main.xml 中定义了以下结构。第一个结构用于跟踪记录的数量。第二个用于记录数据。作者定义并使用两个重叠结构来跟踪记录文件的偏移量。

typedef struct _HEADER {
        DWORD           numRecords;
        DWORD           numNonEmptyRecords;
    } HEADER; /* 8bytes */

typedef struct _RECORD { 
    DWORD           referenceCount;  
    SYSTEMTIME      recordCreationTime;
    SYSTEMTIME      recordLastRefernceTime;
    SYSTEMTIME      recordUpdateTime;
    TCHAR           dataString[STRING_SIZE];
} RECORD; /* 308bytes */

LARGE_INTEGER currentPtr;
OVERLAPPED ov = {0, 0, 0, 0, NULL}, ovZero = {0, 0, 0, 0, NULL};

创建记录后。可以提示用户读取、写入或删除记录。用户输入的记录保存在recNo中。

currentPtr.QuadPart = (LONGLONG)recNo * sizeof(RECORD) + sizeof(HEADER);
ov.Offset = currentPtr.LowPart;
ov.OffsetHigh = currentPtr.HighPart;

谁能解释一下 LARGE_INTEGR currentPtr 的值是如何计算的? 什么是联合?我查看了 windbg 中的示例,但我不明白 currentPtr.LowPartcurrentPtr.HighPart 是如何计算的。下面是使用 OVERLAPPED 结构调用文件读取操作的示例。

ReadFile (hFile, &record, sizeof (RECORD), &nXfer, &ov)

【问题讨论】:

    标签: c windows debugging winapi windbg


    【解决方案1】:

    联合为内存中的同一位置提供不同的名称和类型。因此,如果 LARGE_INTEGER 联合存储在位置 0x1000,并且由于 X86 是小端:

    LARGE_INTEGER.QuadPart is 64 bit integer at 0x1000
    LARGE_INTEGER.LowPart  is the lower 32 bits of the 64 bit integer at 0x1000.
    LARGE_INTEGER.HighPart is the upper 32 bits of the 64 bit integer at 0x1004.
    

    OVERLAPPED 用于异步 I/O。重叠模式下的读取或写入调用将立即返回,并在 I/O 完成时发出 OVERLAPPED 结构中指定的事件。

    关于 OVERLAPPED 结构的 MSDN 文章:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx

    在 32 位模式下,Offset 将与 Pointer 共享内存,在 64 位模式下,Offset 和 OffsetHigh 将与 Pointer 共享内存。 Offset 和 OffsetHigh 是输入,而 Pointer 在内部使用。 InternalHigh 的命名很糟糕,因为它现在报告传输的字节数,并且可能会再次更改。内部现在是一种状态。

    【讨论】:

    • 顺便说一句,我被告知(严格来说)以这种方式使用联合违反了语言规则。但是一段时间以来,Windows 应用程序已经成为一种常见的做法,所以除非你特别挑剔,否则我不会担心它。 :-)
    • @HarryJohnston - Windows API 是 C89 或更早版本,因此在 union 的这个 C(不是 C++)参考中,联合的使用似乎不是问题。这是使用type punning 的方法之一。我删除了我之前的 cmets。
    • 有趣。我没有意识到 C 规则在这方面与 C++ 规则不同。当然,很多软件都是 C++,但如果你使用的是 Win32 API,我想编译器在这方面或多或少必须与 C 二进制兼容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    相关资源
    最近更新 更多