Я пытаюсь увеличить 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});
Вы можете просто напрямую использовать 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 ++, является атомарной операцией.
В качестве проблемы, решаемой @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.