Выделение памяти

Приложения должны выделять память для этих данных; TAPI и поставщик услуг предоставляют данные. Если операция является асинхронной, данные будут недоступны до тех пор, пока асинхронное ответное сообщение не укажет на успешное выполнение.

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

  DWORD  dwTotalSize;
  DWORD  dwNeededSize;
  DWORD  dwUsedSize; 
    <fixed size fields> 
  DWORD  dw<VarSizeField1>Size;
  DWORD  dw<VarSizeField1>Offset; 
    <fixed size fields> 
  DWORD  dw<VarSizeField2>Size;
  DWORD  dw<VarSizeField2>Offset; 
    <common extensions> 
    <var sized field1> 
    <var sized field2>

Член dwTotalSize — это размер в байтах, выделенный для этой структуры данных. Он помечает конец структуры данных и задается приложением перед вызовом функции, которая использует эту структуру данных. Функция не считывает и не записывает данные, превышающие этот размер. Приложение должно задать член dwTotalSize , чтобы указать общее количество байтов, выделенных для TAPI для возврата содержимого структуры.

TAPI заполняет элемент dwNeededSize . Он указывает, сколько байтов требуется для возврата всех запрошенных данных. Наличие полей изменяющегося размера часто не позволяет приложению оценить размер структуры данных, необходимый для выделения. Это поле возвращает количество байтов, фактически необходимых для данных. Это число может быть меньше, равно или больше , чем dwTotalSize, и оно включает пространство для самого члена dwTotalSize . Если размер больше, возвращаемая структура заполняется только частично. Если поля, необходимые для приложения, доступны в частичной структуре, больше ничего делать не нужно. В противном случае приложение должно выделить структуру по крайней мере размера dwNeededSize и снова вызвать функцию. Как правило, на этот раз достаточно места, чтобы вернуть всю информацию, хотя вполне возможно, что размер мог бы увеличиться снова.

TAPI заполняет элемент dwUsedSize , если он возвращает данные в приложение, чтобы указать фактический размер в байтах части структуры данных, содержащей полезные данные. Например, если выделенная структура была слишком мала, а усеченное поле имеет изменяющийся размер, dwNeededSize больше dwTotalSize, а усеченное поле остается пустым. Таким образом, член dwUsedSize может быть меньше , чем dwTotalSize. Частичные значения полей не возвращаются.

После этого заголовка находится фиксированная часть структуры данных. Он содержит обычные поля и пары размера и смещения, описывающие фактические поля изменчивого размера. Поле смещения содержит смещение поля изменяющегося размера от начала записи в байтах. Поле size содержит размер поля изменяющегося размера в байтах. Если поле изменяемого размера пустое, то поле размера равно нулю, а смещение равно нулю. Поля с изменяющимся размером, которые будут усечены, если общий размер структуры недостаточен, остаются пустыми. Это значит, что их поле размера равно нулю, а смещение — нулю. Поля изменяемого размера следуют за фиксированными полями.

Если поставщик услуг должен заполнить элемент переменной, TAPI инициализирует соответствующие элементы размера и смещения до нуля. Если поставщик услуг заполняет элемент переменной, он должен задать соответствующие элементы размера и смещения соответствующим значениям, включая dwUsedSize и dwNeededSize , если он задает элементы переменной. Поставщик услуг не должен усекать элемент переменной, чтобы он помещался в доступное пространство.

Поставщик услуг должен запускать переменные члены сразу после фиксированных элементов структуры и оставить дополнительное пространство в конце выделенной памяти, чтобы TAPI могли использовать его для членов переменной длины. Он может размещать элементы переменной в любом порядке, но они должны быть смежными.