Скорее всего, новая сборка отличается не только версией Windows, но вы также компилируете для 64-битной, тогда как ранее вы компилировали для 32-битной.
Обновление : OP уточнил, что обе сборки являются 64-битными, но это легко объяснить;см. ниже.
Это приведение к DWORD
концептуально неверно даже в Windows 7/32 бит.Действительно, определение API требует ULONG_PTR
, который является целым типом без знака, достаточно большим, чтобы содержать указатель без потери данных.Таким образом, это 32-битный тип при компиляции для 32-битных, 64-битных при компиляции для 64-битных.
Вместо этого вы приводите указатель к DWORD
;DWORD
всегда является 32-битным беззнаковым типом, поэтому при сборке для 32-битной Windows все идет гладко (указателям нужно не более 32-битной для того, чтобы с другой стороны они остались целыми), но в 64-битной Windows вы теряете 32-битную верхнюювашего указателя.
Теперь, это работает даже на 64-битной Windows 7 ;почему?
Как объяснено в комментариях, этот указатель исходит из кучи, и по умолчанию в Windows 7 куча начинает предоставлять память из «малой» части 64-битного адресного пространства;следовательно, если вы не потребляете много памяти, вы всегда будете получать адреса с старшими 32 битами в ноль, так что они выживут даже с отрубленными старшими 32 битами.
Этоизменено начиная с Windows 8 , поскольку ASLR (по умолчанию включается компоновщиком при сборке 64-битных исполняемых файлов) рандомизирует положение кучи в виртуальном адресном пространстве, что означает, что вы получите указатели с ненулевым верхним 32биты, которые будут сильно повреждены актерами на DWORD
.
Короче говоря: исправьте ваш каст 1 и все будет работать нормально.Кроме того, в будущем всегда будьте осторожны с приведением указателя к целочисленному типу, который не заканчивается на _ptr
или _PTR
- есть хорошие шансы, что вы делаете ошибку.
Примечания
- Строго говоря, стандарт IIRC требует "прохождения"
void *
, чтобы эти приведения работали правильно, т.е.гарантируется только для void *
(а может быть char *
? Мне придется проверить стандарт), поэтому должно быть (ULONG_PTR)(LPVOID)pContext
, если pContext
уже не void *
.Тем не менее, это Win32, я уверен, что он гарантированно будет работать даже без дополнительного приведения.