Варавнивание полей структуры

Тема в разделе "LANGS.C", создана пользователем Quark, 21 авг 2007.

  1. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    есть структурка из DDK:

    Код (Text):
    1. typedef struct _SCSI_BUS_DATA {
    2.     UCHAR NumberOfLogicalUnits;
    3.     UCHAR InitiatorBusId;
    4.     ULONG InquiryDataOffset;
    5. }SCSI_BUS_DATA, *PSCSI_BUS_DATA;
    понять не мог - почему в ней данные кривые... глянул в ольку - оказалось что каждое поле этой стр-ры должно выравниваться на 4б, то есть

    Код (Text):
    1. db NumberOfLogicalUnits
    2. rb 3
    3. db InitiatorBusId
    4. rb 3
    5. dd InquiryDataOffset
    как заставить VC делать такое чудо?
     
  2. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Код (Text):
    1. #include <pshpack1.h>
    2. #include <pshpack2.h>
    3. #include <pshpack4.h>
    4. #include <pshpack8.h>
    5. #include <poppack.h>
    Без выравнивания, выравнивание на 2 байта, на 4, на 8 и восстановление предыдущего режима соответственно. Если хочется, можно то же самое через #pragma pack, но первый способ лучше.
     
  3. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    хм.. Всё-равно какой-то бред генерирует:

    Код (Text):
    1. #include <pshpack8.h>
    2.  
    3. typedef struct _SCSI_INQUIRY_DATA {
    4.     UCHAR PathId;
    5.     UCHAR TargetId;
    6.     UCHAR Lun;
    7.     BOOLEAN DeviceClaimed;
    8.     ULONG InquiryDataLength;
    9.     ULONG NextInquiryDataOffset;
    10.     UCHAR InquiryData[1];
    11. }SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
    12.  
    13.  
    14. typedef struct _SCSI_BUS_DATA {
    15.     UCHAR NumberOfLogicalUnits;
    16.     UCHAR InitiatorBusId;
    17.     ULONG InquiryDataOffset;
    18. }SCSI_BUS_DATA, *PSCSI_BUS_DATA;
    19.  
    20. #include <poppack.h>
    21.  
    22. ...
    23.  
    24. pScsiInqueryData = (PSCSI_INQUIRY_DATA)((PCHAR)pScsiBusData + pScsiBusData->InquiryDataOffset);
    25.  
    26. /*
    27. 00401091  |. 8B7E 04        MOV EDI,DWORD PTR DS:[ESI+4]       ; тут esi = pScsiBusData
    28. 00401094  |. 03FE           ADD EDI,ESI
    29. */
    Почему [esi+4], когда должен быть [esi+0C]
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Quark
    Потому, что все эти pshpack относятся к выравниванию размера структуры, а поля внутри структуры выравниваются на размер полей, т.е. однобайтные uchar мог иметь любое смещение, а смещение 4-байтного ulong должно быть кратно 4-м - так оно и получается
    А чтобы повторить супервыравненную структуру из DDK можно наоборот отключить выравнивание (pshpack1) и добавить выравнивающие байты\ворды вручную (типа unused или padd)
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а кто мешает написать не UCHAR а ULONG?

    typedef struct _SCSI_BUS_DATA {
    ULONG NumberOfLogicalUnits;
    ULONG InitiatorBusId;
    ULONG InquiryDataOffset;
    }SCSI_BUS_DATA, *PSCSI_BUS_DATA;

    или так:

    typedef struct _SCSI_BUS_DATA {
    union {
    UCHAR NumberOfLogicalUnits;
    ULONG dummy1;
    };
    union {
    UCHAR InitiatorBusId;
    ULONG dummy2;
    };
    ULONG InquiryDataOffset;
    }SCSI_BUS_DATA, *PSCSI_BUS_DATA;
     
  6. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    Зотелось бы как и в DDK её описать, хотя, сделаю как Great, а то с этими выравниваниями чёрт ногу сломит.