Как увеличить LARGE_INTEGER

Я пытаюсь увеличить LARGE_INTEGER в C ++, но я получаю следующую ошибку.

Ошибка 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});

2

Решение

Вы можете просто напрямую использовать Quadpart. Обратите внимание, что это целое число длиной 64 бита. также известен как long long и __int64 компилятором MS и gcc. Поскольку это простой старый тип данных, компиляторы поддерживают все арифметические и побитовые операции, выполняемые с ним.

Определение БОЛЬШОГО ИНТЕГЕРА

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, вы можете манипулировать LARGE_INTEGER так же, как любое длинное целое число …

Приращение:

li.QuadPart++;

добавив:

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

так далее…

li.QuadPart = 123456LL * 5;

ВАЖНО: MS использует объединение LARGE_INTEGER для передачи таких длинных длинных значений как по историческим причинам, так и для принудительного выравнивания длинных длинных. Некоторые из API Windows будут зависать, если Quadpart не выровнен правильно. Поэтому просто приведение __int64 * к LARGE_INTEGER * при вызовах Windows API не является хорошей практикой.

В 64-битных окнах 64-битное приращение, т.е. li.Quadpart ++, является атомарной операцией.

2

Другие решения

В качестве проблемы, решаемой @CodyGray в комментариях, я предложил это решение. операция еще атомная, так как atomic_store касается только переменных x а также y являются локальными для потока и метода.

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.
1

По вопросам рекламы [email protected]