Compartilhar via


O atributo represent_as

O atributo [ represent_as] permite especificar como um tipo de dados transmitível específico é representado para o aplicativo. Isso é feito especificando o nome do tipo representado para um tipo de transmissão conhecido e fornecendo as rotinas de conversão. Você também deve fornecer as rotinas para liberar a memória usada pelos objetos de tipo de dados.

Use o atributo [represent_as] para apresentar um aplicativo com um tipo de dados diferente, possivelmente não transacionável, em vez do tipo que é realmente transmitido entre o cliente e o servidor. Também é possível que o tipo que o aplicativo manipula possa ser desconhecido no momento da compilação MIDL. Quando você escolhe um tipo de transmissão bem definido, não precisa se preocupar com a representação de dados no ambiente heterogêneo. O atributo [represent_as] pode tornar seu aplicativo mais eficiente reduzindo a quantidade de dados transmitidos pela rede.

O atributo [represent_as] é semelhante ao atributo [ transmit_as]. No entanto, enquanto [transmit_as] permite especificar um tipo de dados que será usado para transmissão, [represent_as] permite especificar como um tipo de dados é representado para o aplicativo. O tipo representado não precisa ser definido nos arquivos processados em MIDL; ele pode ser definido no momento em que os stubs são compilados com o compilador C. Para fazer isso, use a diretiva include no ACF (arquivo de configuração de aplicativo) para compilar o arquivo de cabeçalho apropriado. Por exemplo, o ACF a seguir define um tipo local para o aplicativo, repr_type, para o tipo transmitível named_type:

typedef [represent_as(repr_type) [, type_attribute_list] named_type;

A tabela a seguir descreve as quatro rotinas fornecidas pelo programador.

Rotina Descrição
named_type_from_local Aloca uma instância do tipo de rede e converte do tipo local para o tipo de rede.
named_type_to_local Converte do tipo de rede para o tipo local.
named_type_free_local Libera memória alocada por uma chamada para a rotina de named_type_to_local , mas não o tipo em si.
named_type_free_inst Libera o armazenamento para o tipo de rede (ambos os lados).

 

Além dessas quatro rotinas fornecidas pelo programador, o tipo nomeado não é manipulado pelo aplicativo. O único tipo visível para o aplicativo é o tipo representado. O aplicativo usa o nome de tipo representado em vez do nome de tipo transmitido nos protótipos e stubs gerados pelo compilador. Você deve fornecer o conjunto de rotinas para ambos os lados.

Para objetos named_type temporários, o stub chamará named_type_free_inst para liberar qualquer memória alocada por uma chamada para named_type_from_local.

Se o tipo representado for um ponteiro ou contiver um ponteiro, a rotina named_type_to_local deverá alocar memória para os dados aos quais os ponteiros apontam (o próprio objeto de tipo representado é manipulado pelo stub da maneira usual). Para parâmetros [ out] e [ in, out] de um tipo que contém [represent_as ou um de seus componentes, a rotina de named_type_free_local é chamada automaticamente para os objetos de dados que contêm o atributo . Para parâmetros [in] , a rotina de named_type_free_local será chamada somente se o atributo [represent_as] tiver sido aplicado ao parâmetro . Se o atributo tiver sido aplicado aos componentes do parâmetro , a * rotina _free_local não será chamada. Rotinas de liberação não são chamadas para os dados inseridos e chamadas no máximo uma vez (relacionadas ao atributo de nível superior) para um parâmetro somente [in] .

Observação

É possível aplicar os atributos [transmit_as] e [represent_as] ao mesmo tipo. Ao realizar marshaling de dados, a conversão de tipo [represent_as] é aplicada primeiro e, em seguida, a conversão [transmit_as] é aplicada. A ordem é invertida ao cancelar a inalação de dados. Assim, ao realizar marshaling, *_from_local aloca uma instância de um tipo nomeado e a converte de um objeto de tipo local para o objeto de tipo nomeado temporário. Esse objeto é o objeto de tipo apresentado usado para a rotina *_to_xmit . A rotina *_to_xmit aloca um objeto de tipo transmitido e o converte do objeto apresentado (nomeado) para o objeto transmitido.

 

Uma matriz de inteiros longos pode ser usada para representar uma lista vinculada. Dessa forma, o aplicativo manipula a lista e a transmissão usa uma matriz de inteiros longos quando uma lista desse tipo é transmitida. Você pode começar com uma matriz, mas usar um constructo com uma matriz aberta de inteiros longos é mais conveniente. O exemplo a seguir mostra como fazer isso.

/* IDL definitions */
 
typedef struct_lbox 
{
    long        data;
    struct_lbox *        pNext;
} LOC_BOX, * PLOC_BOX;
 
/* The definition of the local type visible to the application, 
as shown above, can be omitted in the IDL file. See the include 
in the ACF file. */
 
typedef struct_xmit_lbox 
{
    short        Size;
    [size_is(Size)] long DaraArr[];
} LONGARR;
 
void WireTheList( [in,out] LONGARR * pData );
 
/* ACF definitions */
 
/* If the IDL file does not have a definition for PLOC_BOX, you 
can still ready it for C compilation with the following include 
statement (notice that this is not a C include): 
include "local.h";*/
 
typedef [represent_as(PLOC_BOX)] LONGARR;

Observe que os protótipos das rotinas que usam o tipo LONGARR são exibidos nos arquivos Stub.h como PLOC_BOX no lugar do tipo LONGARR . O mesmo se aplica aos stubs apropriados no arquivo Stub_c.c.

Você deve fornecer as quatro funções a seguir:

void __RPC_USER
LONGARR_from_local(
    PLOC_BOX __RPC_FAR * pList,
    LONGARR __RPC_FAR * _RPC_FAR * ppDataArr );
 
void __RPC_USER
LONGARR_to_local(
    LONGARR __RPC_FAR * _RPC_FAR * ppDataArr,
    PLOC_BOX __RPC_FAR * pList );
 
void __RPC_USER
LONGARR_free_inst(
    LONGARR __RPC_FAR * pDataArr);
 
void __RPC_USER
LONGARR_free_local(
    PLOC_BOX __RPC_FAR * pList );

As rotinas mostradas acima fazem o seguinte:

  • A rotina LONGARR_from_local conta os nós da lista, aloca um objeto LONGARR com sizeof(LONGARR) + Count*sizeof(long), define o campo Tamanho como Count e copia os dados para o campo DataArr .
  • A rotina de LONGARR_to_local cria uma lista com nós de tamanho e transfere a matriz para os nós apropriados.
  • A rotina LONGARR_free_inst não libera nada neste caso.
  • A rotina de LONGARR_free_local libera todos os nós da lista.