Как объявить объединение внутри структуры записи? - PullRequest
6 голосов
/ 09 ноября 2019

Я пытаюсь определить тип TWaveFormatExtensible, но я не уверен, правильно ли я объявляю объединение Samples. Вот оригинальное объявление из заголовочного файла (Windows SDK 10.0.17763.0):

typedef struct {
    WAVEFORMATEX    Format;
    union {
        WORD wValidBitsPerSample;       /* bits of precision  */
        WORD wSamplesPerBlock;          /* valid if wBitsPerSample==0 */
        WORD wReserved;                 /* If neither applies, set to zero. */
    } Samples;
    DWORD           dwChannelMask;      /* which channels are */
                                        /* present in stream  */
    GUID            SubFormat;
}

И вот что я пробовал:

type
  TWAVEFORMATEX = record
    wFormatTag: Word;
    nChannels: LongWord;
    nSamplesPerSec: Word;
    nAvgBytesPerSec: LongWord;
    nBlockAlign: Word;
    wBitsPerSample: Word;
    cbSize: Word;
  end;

  TWaveFormatExtensible = record
    Format: TWAVEFORMATEX;
    dwChannelMask: LongWord;
    SubFormat: Integer;
    case Word of
      0: (wValidBitsPerSample: Word;);
      1: (wSamplesPerBlock: Word;);
      2: (wReserved: Word;);
  end;

Но это не правильно. Как объявить объединение внутри структуры записей в Delphi?

1 Ответ

11 голосов
/ 09 ноября 2019

Поля структуры должны быть в том же порядке, что и в исходном (C ++) объявлении. Но есть проблема: оригинальное объявление помещает вариант Samples в середину записи, а это не разрешено в Delphi.

Вы можете решить эту проблему, объявив вариантную часть как отдельную запись, а затем включить эту запись в качестве поля в окончательную структуру.

TWaveFormatExtensibleSamples = record
case Word of
  0: (wValidBitsPerSample: Word;);
  1: (wSamplesPerBlock: Word;);
  2: (wReserved: Word;);
end;

и затем построить окончательную структуру:

TWaveFormatExtensible = record
  Format: TWAVEFORMATEX;
  Samples: TWaveFormatExtensibleSamples;
  dwChannelMask: DWORD;
  SubFormat: TGUID; 
end;

edit : документация для записей с вариантами деталей, состояние:

Тип записи может иметь вариантную часть, которая выглядит какзаявление о ситуацииВариантная часть должна следовать за другими полями в объявлении записи.

Это относится к вариантным частям без вложения декларации записи.

Однако, как указал Реми Лебо, a запись с вариантной частью может быть непосредственно объявлена ​​в объявлении TWaveFormatExtensible как часть структуры, между другими полями:

TWaveFormatExtensible = record
  Format: TWAVEFORMATEX;
  Samples: record
    case Word of
    0: (wValidBitsPerSample: Word;);
    1: (wSamplesPerBlock: Word;);
    2: (wReserved: Word;);
  end;
  dwChannelMask: DWORD;
  SubFormat: TGUID;
end;

Таким образом, это можно использовать так же, как и отдельно объявленную TWaveFormatExtensibleSamples запись.

...