Почему структура GESTUREINFO в Delphi занимает 48 байт и связь с 8-байтным выравниванием
При переводе частей заголовочного файла winuser.h на Delphi, разработчики часто сталкиваются с неожиданными размерами структур. Одной из таких структур является GESTUREINFO, которая, по непонятным на первый взгляд причинам, должна занимать ровно 48 байт. Разберемся, почему это так и что за этим стоит.
Структура GESTUREINFO и ее элементы
Структура GESTUREINFO в C и C++ выглядит следующим образом:
С первого взгляда, кажется, что размер структуры должен быть 40 байт, если учитывать 4-байтное выравнивание. Однако, на практике, размер оказывается 48 байт, что принимается соответствующей функцией.
8-байтное выравнивание
Подтвержденный ответ на вопрос о размере структуры GESTUREINFO заключается в том, что Windows API требует 8-байтного выравнивания. Это связано с конвенциями, принятыми в Microsoft Windows. Согласно MSDN, это связано с тем, что самый большой целочисленный тип, поддерживаемый в данный момент, имеет размер 8 байт. Следовательно, 8-байтное выравнивание гарантирует, что все целочисленные типы будут правильно выровнены.
Альтернативный ответ и дополнительные пояснения
Альтернативный ответ подтверждает, что именно 8-байтное выравнивание приводит к тому, что элемент ullArguments перемещается на правильную позицию, с четырьмя байтами подкачки для перехода с смещения 28 до 32, и еще четырьмя байтами подкачки в конце, чтобы гарантировать, что массив структур все еще имеет этот элемент выровненным должным образом.
В Delphi начиная с версии 2010, тип GESTUREINFO уже определен в файле Windows.pas. Однако, если вы работаете с более ранними версиями, вам придется самостоятельно адаптировать определение структуры.
Пример кода на Object Pascal
Давайте рассмотрим, как может выглядеть адаптация структуры GESTUREINFO для использования в Delphi:
type
TPOINTS = record
x, y: Integer;
end;
TGESTUREINFO = record
cbSize: UIntPtr;
dwFlags: DWORD;
dwID: DWORD;
hwndTarget: HWND;
ptsLocation: TPOINTS;
dwInstanceID: DWORD;
dwSequenceID: DWORD;
ullArguments: Int64;
cbExtraArgs: UINT;
end;
В этом примере мы используем UIntPtr для cbSize, чтобы обеспечить 8-байтное выравнивание. Int64 используется для ullArguments, чтобы соответствовать типу ULONGLONG в C/C++.
Итак, размер структуры GESTUREINFO в 48 байт обусловлен требованиями 8-байтного выравнивания, принятыми в Windows API, что является ключевым моментом при работе с большими целочисленными типами и структурами в Delphi.
Структура `GESTUREINFO` в Delphi занимает 48 байт и требует 8-байтного выравнивания из-за требований Windows API к выравниванию целочисленных типов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.