【问题标题】:How to increment LARGE_INTEGER如何增加 LARGE_INTEGER
【发布时间】:2017-08-11 20:39:14
【问题描述】:

我正在尝试在 c++ 中增加 LARGE_INTEGER,但出现以下错误。

错误 C2397:从“LONGLONG”到“DWORD”的转换需要缩小转换

我不知道我做错了什么。这是一个非常简单的问题,我试图重建项目,但错误不会消失。

std::atomic<LARGE_INTEGER> value; // this field is defined in header

这些行是我尝试过的,它们都给出了相同的错误。

// inside a method in cpp
value = {get_some_large_integer().QuadPart + 1};

value = LARGE_INTEGER{get_some_large_integer().QuadPart + 1};

value = static_cast<LARGE_INTEGER>(LARGE_INTEGER{get_some_large_integer().QuadPart + 1});

【问题讨论】:

  • 是的,我必须使用LARGE_INTEGER,因为我仅限于使用这种数据类型的库窗口函数。是的,value = {get_some_large_integer()}; 也适用于我,但value = {get_some_large_integer().QuadPart}; 给出了错误。似乎递增不是问题,但访问 QuadPart 是一个问题。 @CodyGray
  • @CodyGray 我明白了,但是 ctor 不接受 64 位值很奇怪。如果它的 64 位值应该有,那就太奇怪了!
  • 它正在从li.QuadPart 初始化一个LARGE_INTEGER,这就是问题所在。不用std::atomic 试试。你会遇到同样的问题。无法直接从 64 位值构造 LARGE_INTEGER(因为不幸的是,C++ 没有 designated initializers)。您需要使用两个 32 位半部分来构建它。我不知道这里有一个好的解决方案。也许其他人会。
  • 自 VS 2008 以来,我在处理 64 位整数时从未遇到任何问题。问题可能是由于 LARGE_INTEGER 是一个联合,而不是一个结构。

标签: c++ compiler-errors increment


【解决方案1】:

您可以直接使用 Quadpart。请注意,它是一个 64 位长整数。 MS 编译器和 gcc 也将其称为 long long 和 __int64。由于它是一种普通的旧数据类型,因此编译器支持使用它完成的所有算术和按位运算。

大整数的定义

typedef union _LARGE_INTEGER {
  struct {
    DWORD LowPart;
    LONG  HighPart;
  };
  struct {
    DWORD LowPart;
    LONG  HighPart;
  } u;
  LONGLONG QuadPart;       // <--  this is a 64 bit integer.
} LARGE_INTEGER, *PLARGE_INTEGER;

LARGE_INTEGER 是一个普通的 C 联合,因此不提供任何构造函数。但是,您可以使用 C 聚合初始化程序将其初始化为零。

LARGE_INTEGER li = {};  // initialize to zero.

使用 QuadPart,您可以像操作任何 long long 整数一样操作 LARGE_INTEGER...

递增:

li.QuadPart++;

添加:

__int128 i = 123456LL;
 li.QuadPart += i;

等等……

li.QuadPart = 123456LL * 5;

重要提示:MS 使用 LARGE_INTEGER 联合来传递这样的 long long 值,这既是出于历史原因,也是为了强制 long long 对齐。如果 Quadpart 未正确对齐,某些 Windows API 将崩溃。因此,在对 Windows API 的调用中简单地将 __int64* 转换为 LARGE_INTEGER* 并不是好的做法。

在 64 位窗口中,64 位增量即 li.Quadpart++ 是原子操作。

【讨论】:

  • 当然,你可以这样做,但你扔掉了问题的std::atomic 部分。
【解决方案2】:

@CodyGray 在 cmets 中解决的问题是我想出了这个解决方案。该操作仍然是原子的,因为只关注atomic_store,变量xy 是线程和方法的本地变量。

LARGE_INTEGER x = get_some_large_integer();
LONGLONG y = x.QuadPart + 1; // increment
x.LowPart = (LONG)y;
x.HighPart = (LONG)(y >> 32);
value = x; // atomic operation.

【讨论】:

  • 如果这可靠地增加你的整数,那么你首先不需要 std::atomic。
  • value = x.QuadPart + 1;会不会简单得多?
  • 为什么不做x.QuadPart = y。四部分; ???还是`++x.QuadPart;?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
  • 2010-12-24
相关资源
最近更新 更多