O atributo transmit_as
O atributo [transmit_as] oferece uma maneira de controlar o marshaling de dados sem se preocupar com o marshaling de dados em um nível baixo, ou seja, sem se preocupar com tamanhos de dados ou troca de bytes em um ambiente heterogêneo. Ao permitir que você reduza a quantidade de dados transmitidos pela rede, o atributo [transmit_as] pode tornar seu aplicativo mais eficiente.
Use o atributo [transmit_as] para especificar um tipo de dados que os stubs RPC transmitirão pela rede em vez de usar o tipo de dados fornecido pelo aplicativo. Você fornece rotinas que convertem o tipo de dados de e para o tipo usado para transmissão. Você também deve fornecer rotinas para liberar a memória usada para o tipo de dados e o tipo transmitido. Por exemplo, o seguinte define xmit_type como o tipo de dados transmitido para todos os dados do aplicativo especificados como sendo do tipo type_spec:
typedef [transmit_as (xmit_type)] type_spec type;
A tabela a seguir descreve os quatro nomes de rotina fornecidos pelo programador. Type é o tipo de dados conhecido pelo aplicativo e xmit_type é o tipo de dados usado para transmissão.
Rotina | Descrição |
---|---|
type_to_xmit | Aloca um objeto do tipo transmitido e converte do tipo de aplicativo para o tipo transmitido pela rede (chamado de chamador e objeto). |
Type_from_xmit | Converte do tipo transmitido para o tipo de aplicativo (chamado de chamador e objeto). |
Type_free_inst | Libera recursos usados pelo tipo de aplicativo (objeto chamado somente). |
Type_free_xmit | Libera o armazenamento retornado pela rotina de to_xmit type*_*(chamado de chamador e objeto). |
Além dessas quatro funções fornecidas pelo programador, o tipo transmitido não é manipulado pelo aplicativo. O tipo transmitido é definido apenas para mover dados pela rede. Depois que os dados são convertidos no tipo usado pelo aplicativo, a memória usada pelo tipo transmitido é liberada.
Essas rotinas fornecidas pelo programador são fornecidas pelo cliente ou pelo aplicativo de servidor com base nos atributos direcionais. Se o parâmetro for somente [in] , o cliente transmitirá para o servidor. O cliente precisa das funções type_to_xmit e type_free_xmit . O servidor precisa das funções type_from_xmit e type_free_inst . Para um parâmetro [out]-only, o servidor transmite para o cliente. O aplicativo de servidor deve implementar as funções type_to_xmit e type_free_xmit , enquanto o programa cliente deve fornecer a função type_from_xmit . Para os objetos de xmit_type temporários, o stub chamará type*_*free_xmit para liberar qualquer memória alocada por uma chamada para type_to_xmit.
Determinadas diretrizes se aplicam à instância do tipo de aplicativo. Se o tipo de aplicativo for um ponteiro ou contiver um ponteiro, a rotina type_from_xmit deverá alocar memória para os dados para os quais os ponteiros apontam (o próprio objeto de tipo de aplicativo é manipulado pelo stub da maneira usual).
Para parâmetros [out] e [in, out] out] ou um de seus componentes, de um tipo que contém o atributo [transmit_as] , a rotina type_free_inst é chamada automaticamente para os objetos de dados que têm o atributo . Para em parâmetros, a rotina type_free_inst será chamada somente se o atributo [transmit_as] tiver sido aplicado ao parâmetro . Se o atributo tiver sido aplicado aos componentes do parâmetro , a rotina type_free_inst não será chamada. Não há chamadas de liberação para os dados inseridos e no máximo uma chamada (relacionada ao atributo de nível superior) para um parâmetro somente in .
Com efeito com MIDL 2.0, o cliente e o servidor devem fornecer todas as quatro funções. Por exemplo, uma lista vinculada pode ser transmitida como uma matriz de tamanho. A rotina type_to_xmit orienta a lista vinculada e copia os dados ordenados em uma matriz. Os elementos da matriz são ordenados para que os muitos ponteiros associados à estrutura de lista não precisem ser transmitidos. A rotina type_from_xmit lê a matriz e coloca seus elementos em uma estrutura de lista vinculada.
A lista vinculada dupla (DOUBLE_LINK_LIST) inclui dados e ponteiros para os elementos de lista anteriores e seguintes:
typedef struct _DOUBLE_LINK_LIST
{
short sNumber;
struct _DOUBLE_LINK_LIST * pNext;
struct _DOUBLE_LINK_LIST * pPrevious;
} DOUBLE_LINK_LIST;
Em vez de enviar a estrutura complexa, o atributo [transmit_as] pode ser usado para enviá-lo pela rede como uma matriz. A sequência de itens na matriz mantém a ordenação dos elementos na lista a um custo menor:
typedef struct _DOUBLE_XMIT_TYPE
{
short sSize;
[size_is(sSize)] short asNumber[];
} DOUBLE_XMIT_TYPE;
O atributo [transmit_as] aparece no arquivo IDL:
typedef [transmit_as(DOUBLE_XMIT_TYPE)] DOUBLE_LINK_LIST DOUBLE_LINK_TYPE;
No exemplo a seguir, ModifyListProc define o parâmetro do tipo DOUBLE_LINK_TYPE como um parâmetro [in, out] :
void ModifyListProc([in, out] DOUBLE_LINK_TYPE * pHead)
As quatro funções definidas pelo programador usam o nome do tipo nos nomes de função e usam os tipos apresentados e transmitidos como tipos de parâmetro, conforme necessário:
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);