Share via


Attributo represent_as

L'attributo [ represent_as] consente di specificare la modalità di rappresentazione di un particolare tipo di dati trasmettebile all'applicazione. Questa operazione viene eseguita specificando il nome del tipo rappresentato per un tipo trasmettebile noto e fornendo le routine di conversione. È inoltre necessario specificare le routine per liberare la memoria utilizzata dagli oggetti del tipo di dati.

Usare l'attributo [represent_as] per presentare un'applicazione con un tipo di dati diverso, possibilmente non trasmettibile, anziché il tipo effettivamente trasmesso tra il client e il server. È anche possibile che il tipo modificato dall'applicazione possa essere sconosciuto al momento della compilazione MIDL. Quando si sceglie un tipo trasmettebile ben definito, non è necessario preoccuparsi della rappresentazione dei dati nell'ambiente eterogeneo. L'attributo [represent_as] può rendere l'applicazione più efficiente riducendo la quantità di dati trasmessi in rete.

L'attributo [represent_as] è simile all'attributo [ transmit_as]. Tuttavia, mentre [transmit_as] consente di specificare un tipo di dati che verrà usato per la trasmissione, [represent_as] consente di specificare la modalità di rappresentazione di un tipo di dati per l'applicazione. Il tipo rappresentato non deve essere definito nei file elaborati MIDL; può essere definito al momento della compilazione degli stub con il compilatore C. A tale scopo, usare la direttiva include nel file di configurazione dell'applicazione (ACF) per compilare il file di intestazione appropriato. Ad esempio, il seguente ACF definisce un tipo locale per l'applicazione , repr_type, per il tipo trasmettebile named_type:

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

Nella tabella seguente vengono descritte le quattro routine fornite dal programmatore.

Routine Descrizione
named_type_from_local Alloca un'istanza del tipo di rete e converte dal tipo locale al tipo di rete.
named_type_to_local Converte dal tipo di rete al tipo locale.
named_type_free_local Libera la memoria allocata da una chiamata alla routine named_type_to_local , ma non al tipo stesso.
named_type_free_inst Libera l'archiviazione per il tipo di rete (entrambi i lati).

 

Oltre a queste quattro routine fornite dal programmatore, il tipo denominato non viene modificato dall'applicazione. L'unico tipo visibile all'applicazione è il tipo rappresentato. L'applicazione usa il nome del tipo rappresentato anziché il nome del tipo trasmesso nei prototipi e negli stub generati dal compilatore. È necessario fornire il set di routine per entrambi i lati.

Per gli oggetti named_type temporanei, lo stub chiamerà named_type_free_inst per liberare qualsiasi memoria allocata da una chiamata a named_type_from_local.

Se il tipo rappresentato è un puntatore o contiene un puntatore, la routine named_type_to_local deve allocare memoria per i dati a cui puntano i puntatori (l'oggetto tipo rappresentato stesso viene manipolato dallo stub nel modo consueto). Per i parametri [ out] e [ in, out] di un tipo che contiene [represent_as o uno dei relativi componenti, la routine named_type_free_local viene chiamata automaticamente per gli oggetti dati che contengono l'attributo . Per i parametri [in] la routine named_type_free_local viene chiamata solo se l'attributo [represent_as] è stato applicato al parametro . Se l'attributo è stato applicato ai componenti del parametro, la *routine _free_local non viene chiamata. Le routine di rilascio non vengono chiamate per i dati incorporati e la chiamata at-most-once (correlata all'attributo di primo livello) per un solo parametro [in].

Nota

È possibile applicare gli attributi [transmit_as] e [represent_as] allo stesso tipo. Quando si esegue il marshalling dei dati, viene applicata prima la conversione del tipo [represent_as] e quindi viene applicata la conversione [transmit_as]. L'ordine viene invertito quando si annullano i dati dimarshaling. Pertanto, quando si esegue il marshalling, *_from_local alloca un'istanza di un tipo denominato e la converte da un oggetto tipo locale all'oggetto tipo denominato temporaneo. Questo oggetto è l'oggetto di tipo presentato utilizzato per la routine *_to_xmit . La routine *_to_xmit alloca quindi un oggetto di tipo trasmesso e lo converte dall'oggetto presentato (denominato) all'oggetto trasmesso.

 

È possibile utilizzare una matrice di interi lunghi per rappresentare un elenco collegato. In questo modo, l'applicazione modifica l'elenco e la trasmissione usa una matrice di interi lunghi quando viene trasmesso un elenco di questo tipo. È possibile iniziare con una matrice, ma l'uso di un costrutto con una matrice aperta di interi lunghi è più pratico. L'esempio seguente illustra come farlo.

/* 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;

Si noti che i prototipi delle routine che usano il tipo LONGARR vengono effettivamente visualizzati nei file Stub.h come PLOC_BOX al posto del tipo LONGARR . Lo stesso vale per gli stub appropriati nel file Stub_c.c.

È necessario fornire le quattro funzioni seguenti:

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

Le routine illustrate in precedenza eseguono le operazioni seguenti:

  • La routine LONGARR_from_local conta i nodi dell'elenco, alloca un oggetto LONGARR con dimensioniof(LONGARR) + Count*sizeof(long), imposta il campo Size su Count e copia i dati nel campo DataArr .
  • La routine LONGARR_to_local crea un elenco con nodi Size e trasferisce la matrice ai nodi appropriati.
  • La routine LONGARR_free_inst libera nulla in questo caso.
  • La routine LONGARR_free_local libera tutti i nodi dell'elenco.