Compartilhar via


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);