Распределение памяти
Приложения должны выделять память для этих данных; 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 dwUsedSize, если он возвращает данные приложению, чтобы указать фактический размер в байтах части структуры данных, содержащей полезные данные. Если, например, выделенная структура была слишком маленькой, и усеченное поле является полем с разными размерами, dwNeededSize больше, чем dwTotalSize, а усеченное поле остается пустым. Поэтому член dwUsedSize может быть меньше dwTotalSize. Частичные значения полей не возвращаются.
После этого заголовка является фиксированной частью структуры данных. Он содержит регулярные поля и пары смещений и размеров, описывающие фактические изменяемые поля. Поле смещения содержит смещение в байтах изменяемого размера поля с начала записи. Поле размера содержит размер в байтах изменяемого размера поля. Если поле с разными размерами пусто, то поле размера равно нулю, а смещение равно нулю. Вариативно размер полей, которые будут усечены, если общий размер структуры недостаточно, остается пустым. То есть поле размера равно нулю, а смещение равно нулю. Вариативно размер полей следует фиксированным полям.
Если поставщик услуг должен заполнить элемент переменной, TAPI инициализирует соответствующий размер и смещение элементов до нуля. Если поставщик услуг заполняет элемент переменной, он должен задать соответствующие элементы размера и смещения соответствующим значениям, включая dwUsedSize и dwNeededSize, если он задает элементы переменной. Поставщик услуг не должен усечь элемент переменной, чтобы он соответствовал доступному пространству.
Поставщик услуг должен запускать члены переменной сразу после фиксированных элементов структуры и оставлять дополнительное пространство в конце выделенной памяти, чтобы TAPI могли использовать его для элементов переменной длины. Он может размещать члены переменной в любом порядке, но элементы должны быть смежными.