Атрибут transmit_as
Атрибут [transmit_as] позволяет управлять маршалингом данных, не беспокоясь о маршале данных на низком уровне, то есть не беспокоясь о размерах данных или переключении байтов в разнородной среде. Благодаря уменьшению объема данных, передаваемых по сети, атрибут [transmit_as] может повысить эффективность приложения.
Атрибут [transmit_as] используется для указания типа данных, который заглушки RPC будут передавать по сети, а не использовать тип данных, предоставленный приложением. Вы предоставляете подпрограммы, которые преобразуют тип данных в тип, используемый для передачи, и из типа. Кроме того, необходимо предоставить подпрограммы для освобождения памяти, используемой для типа данных и передаваемого типа. Например, следующий код определяет xmit_type как тип данных, передаваемый для всех данных приложения, указанных как тип type_spec:
typedef [transmit_as (xmit_type)] type_spec type;
В следующей таблице описаны четыре имени подпрограмм, предоставленных программистом. Тип — это тип данных, известный приложению, а xmit_type — тип данных, используемый для передачи.
Подпрограмма | Описание |
---|---|
type_to_xmit | Выделяет объект передаваемого типа и преобразует тип приложения в тип, передаваемый по сети (вызывающий объект и вызываемый объект). |
Type_from_xmit | Преобразует передаваемый тип в тип приложения (вызывающий объект и вызываемый объект). |
Type_free_inst | Освобождает ресурсы, используемые типом приложения (объект называется только). |
Type_free_xmit | Освобождает хранилище, возвращаемое типом*_*to_xmit подпрограммой (вызывающим объектом и объектом). |
За исключением этих четырех функций, предоставляемых программистом, передаваемый тип не обрабатывается приложением. Передаваемый тип определяется только для перемещения данных по сети. После преобразования данных в тип, используемый приложением, освобождается память, используемая передаваемым типом.
Эти подпрограммы, предоставляемые программистом, предоставляются клиентом или серверным приложением на основе атрибутов направления. Если параметр имеет значение [in] , клиент передает на сервер. Клиенту требуются функции type_to_xmit и type_free_xmit . Серверу требуются функции type_from_xmit и type_free_inst . Для параметра [out]only сервер передает клиенту. Серверное приложение должно реализовывать функции type_to_xmit и type_free_xmit , а клиентская программа должна предоставлять функцию type_from_xmit . Для временных объектов xmit_type заглушка вызывает type*_*free_xmit , чтобы освободить память, выделенную вызовом type_to_xmit.
К экземпляру типа приложения применяются определенные рекомендации. Если тип приложения является указателем или содержит указатель, то подпрограмма type_from_xmit должна выделить память для данных, на которые указывают указатели (сам объект типа приложения управляется заглушки обычным способом).
Для параметров [out] и [in, out] или одного из их компонентов типа, содержащего атрибут [transmit_as] , подпрограмма type_free_inst вызывается автоматически для объектов данных, имеющих атрибут . Для в параметрах подпрограмма type_free_inst вызывается только в том случае, если к параметру применен атрибут [transmit_as] . Если атрибут был применен к компонентам параметра, подпрограмма type_free_inst не вызывается. Нет свободных вызовов для внедренных данных и не более одного вызова (связанного с атрибутом верхнего уровня) для параметра in only.
В случае с MIDL 2.0 и клиент, и сервер должны предоставлять все четыре функции. Например, связанный список может передаваться в виде массива размера. Подпрограмма type_to_xmit выполняет обход связанного списка и копирует упорядоченные данные в массив. Элементы массива упорядочены таким образом, что не нужно передавать множество указателей, связанных со структурой списка. Подпрограмма type_from_xmit считывает массив и помещает его элементы в структуру связанного списка.
Список с двойной связью (DOUBLE_LINK_LIST) содержит данные и указатели на элементы предыдущего и следующего списка:
typedef struct _DOUBLE_LINK_LIST
{
short sNumber;
struct _DOUBLE_LINK_LIST * pNext;
struct _DOUBLE_LINK_LIST * pPrevious;
} DOUBLE_LINK_LIST;
Вместо доставки сложной структуры атрибут [transmit_as] можно использовать для отправки по сети в виде массива. Последовательность элементов в массиве сохраняет порядок элементов в списке с меньшими затратами:
typedef struct _DOUBLE_XMIT_TYPE
{
short sSize;
[size_is(sSize)] short asNumber[];
} DOUBLE_XMIT_TYPE;
Атрибут [transmit_as] отображается в IDL-файле:
typedef [transmit_as(DOUBLE_XMIT_TYPE)] DOUBLE_LINK_LIST DOUBLE_LINK_TYPE;
В следующем примере ModifyListProc определяет параметр типа DOUBLE_LINK_TYPE в виде параметра [in, out] :
void ModifyListProc([in, out] DOUBLE_LINK_TYPE * pHead)
Четыре функции, определяемые программистом, используют имя типа в именах функций и при необходимости используют представленные и передаваемые типы в качестве типов параметров:
void __RPC_USER DOUBLE_LINK_TYPE_to_xmit (
DOUBLE_LINK_TYPE __RPC_FAR * pList,
DOUBLE_XMIT_TYPE __RPC_FAR * __RPC_FAR * ppArray);
void __RPC_USER DOUBLE_LINK_TYPE_from_xmit (
DOUBLE_XMIT_TYPE __RPC_FAR * pArray,
DOUBLE_LINK_TYPE __RPC_FAR * pList);
void __RPC_USER DOUBLE_LINK_TYPE_free_inst (
DOUBLE_LINK_TYPE __RPC_FAR * pList);
void __RPC_USER DOUBLE_LINK_TYPE_free_xmit (
DOUBLE_XMIT_TYPE __RPC_FAR * pArray);