ULARGE_INTEGER联合体的用途是什么?

6

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383742%28v=vs.85%29.aspx

这些应该像这样使用,将两个32位值设置在LowPart和HighPart上,然后对QuadPart执行算术运算。

int a,b,c;
ULARGE_INTEGER u;
...
u.LowPart = a;
u.HighPart = b;
u.QuadPart += c;

如果您要对QuadPart(64位)执行算术运算,那么您需要一台64位处理器,对吗?那么整个问题的重点是什么?为什么不直接将值分配给QuadPart呢?

3个回答

9
你不需要64位处理器就能对64位数据类型进行算术运算。我所知道的所有32位编译器都支持64位整数的算术运算。如果硬件不允许原生算术运算,则编译器必须生成代码来执行算术运算。通常,这将利用编译器RTL中的支持函数。
该结构旨在供那些不提供对64位数据类型的原生支持的编译器使用。你提供的文档也清楚说明了这一点:

注意: 你的C编译器可能会原生支持64位整数。例如,Microsoft Visual C++支持__int64大小的整数类型。有关更多信息,请参阅你的C编译器附带的文档。

不支持原生64位整数的编译器将无法将QUADPART联合成员视为整数。
typedef union _ULARGE_INTEGER {
  struct {
    DWORD LowPart;
    DWORD HighPart;
  };
  struct {
    DWORD LowPart;
    DWORD HighPart;
  } u;
  ULONGLONG QuadPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;

ULONGLONG的定义:

#if !defined(_M_IX86)
 typedef unsigned __int64 ULONGLONG;
#else
 typedef double ULONGLONG;
#endif

当然,过去10年(或更长时间)编写的所有编译器都将原生支持64位整数。但是这个联合体最初是很久以前引入的,当时编译器的情况可能有所不同。在查看Windows头文件时,请始终牢记历史和遗留问题。


不支持本地64位整数的编译器将无法将QUADPART联合成员视为整数。那么在这样的编译器上执行u.QuadPart += c时会发生什么? - Roland
3
从头文件中读取带有#if的引用文本部分。 - Raymond Chen
@RaymondChen 如果在32位编译器上执行“u.LowPart += 100”并且发生溢出,会发生什么? - Roland
我建议添加RTL(运行时库)的定义。我不知道它是什么。 - Roland

5

通常情况下,当您需要将一对32位整数转换为64位整数或反之亦然时,会使用ULARGE_INTEGER

例如,考虑操作FILETIME结构:

void add_millisecond(FILETIME * ft)
{
  ULARGE_INTEGER uli;
  uli.LowPart = ft->dwLowDateTime;
  uli.HighPart = ft->dwHighDateTime;
  uli.QuadPart += 10000;
  ft->dwLowDateTime = uli.LowPart;
  ft->dwHighDateTime = uli.HighPart;
}

由于你只拥有高位和低位部分,因此无法直接赋值QuadPart值。

这行代码 uli.QuadPart += 10000; 在不支持64位整数的编译器上应该无法工作,对吧? - Roland
在只支持32位算术的编译器上,您无法执行 uli.QuadPart += 10000;,而必须按照此处概述的方式进行操作:https://stackoverflow.com/a/45540114/480894 - Roland
@Roland,我不知道有任何现代的Windows编译器只支持32位算术。 - Harry Johnston

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接