Attribut represent_as
L’attribut [ represent_as] vous permet de spécifier la façon dont un type de données transmettable particulier est représenté pour l’application. Pour ce faire, spécifiez le nom du type représenté pour un type transmissible connu et fournissez les routines de conversion. Vous devez également fournir les routines pour libérer la mémoire utilisée par les objets de type de données.
Utilisez l’attribut [represent_as] pour présenter une application avec un type de données différent, éventuellement non transmissible, plutôt que le type qui est effectivement transmis entre le client et le serveur. Il est également possible que le type que l’application manipule soit inconnu au moment de la compilation MIDL. Lorsque vous choisissez un type de transmission bien défini, vous n’avez pas besoin de vous soucier de la représentation des données dans l’environnement hétérogène. L’attribut [represent_as] peut rendre votre application plus efficace en réduisant la quantité de données transmises sur le réseau.
L’attribut [represent_as] est similaire à l’attribut [ transmit_as]. Toutefois, si [transmit_as] vous permet de spécifier un type de données qui sera utilisé pour la transmission, [represent_as] vous permet de spécifier la façon dont un type de données est représenté pour l’application. Le type représenté n’a pas besoin d’être défini dans les fichiers traités MIDL ; il peut être défini au moment où les stubs sont compilés avec le compilateur C. Pour ce faire, utilisez la directive include dans le fichier de configuration d’application (ACF) pour compiler le fichier d’en-tête approprié. Par exemple, l’ACF suivant définit un type local pour l’application, repr_type, pour le type transmettable named_type :
typedef [represent_as(repr_type) [, type_attribute_list] named_type;
Le tableau suivant décrit les quatre routines fournies par le programmeur.
Routine | Description |
---|---|
named_type_from_local | Alloue une instance du type réseau et convertit le type local en type réseau. |
named_type_to_local | Convertit le type réseau en type local. |
named_type_free_local | Libère la mémoire allouée par un appel au named_type_to_local routine, mais pas le type lui-même. |
named_type_free_inst | Libère le stockage pour le type de réseau (des deux côtés). |
En dehors de ces quatre routines fournies par le programmeur, le type nommé n’est pas manipulé par l’application. Le seul type visible par l’application est le type représenté. L’application utilise le nom de type représenté au lieu du nom de type transmis dans les prototypes et les stubs générés par le compilateur. Vous devez fournir l’ensemble de routines pour les deux côtés.
Pour les objets named_type temporaires, le stub appelle named_type_free_inst pour libérer la mémoire allouée par un appel à named_type_from_local.
Si le type représenté est un pointeur ou contient un pointeur, le named_type_to_local routine doit allouer de la mémoire pour les données vers lesquelles pointent les pointeurs (l’objet de type représenté lui-même est manipulé par le stub de la manière habituelle). Pour les paramètres [ out] et [ in, out] d’un type qui contiennent [represent_as ou l’un de ses composants, la routine named_type_free_local est automatiquement appelée pour les objets de données qui contiennent l’attribut. Pour les paramètres [in], la routine named_type_free_local est appelée uniquement si l’attribut [represent_as] a été appliqué au paramètre. Si l’attribut a été appliqué aux composants du paramètre, la *routine _free_local n’est pas appelée. Les routines de libération ne sont pas appelées pour les données incorporées et un appel au plus une fois (lié à l’attribut de niveau supérieur) pour un paramètre [in] uniquement.
Notes
Il est possible d’appliquer les attributs [transmit_as] et [represent_as] au même type. Lors du marshaling des données, la conversion de type [represent_as] est appliquée en premier, puis la conversion [transmit_as] est appliquée. L’ordre est inversé en cas de démarshalation des données. Ainsi, lors du marshaling, *_from_local alloue un instance d’un type nommé et le traduit d’un objet de type local en objet de type nommé temporaire. Cet objet est l’objet de type présenté utilisé pour la routine *_to_xmit . La routine *_to_xmit alloue ensuite un objet de type transmis et le traduit de l’objet présenté (nommé) à l’objet transmis.
Un tableau d’entiers longs peut être utilisé pour représenter une liste liée. De cette façon, l’application manipule la liste et la transmission utilise un tableau d’entiers longs lorsqu’une liste de ce type est transmise. Vous pouvez commencer par un tableau, mais l’utilisation d’une construction avec un tableau ouvert d’entiers longs est plus pratique. L’exemple suivant vous montre comment procéder.
/* 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;
Notez que les prototypes des routines qui utilisent le type LONGARR sont en fait affichés dans les fichiers Stub.h comme PLOC_BOX à la place du type LONGARR . Il en va de même pour les stubs appropriés dans le fichier Stub_c.c.
Vous devez fournir les quatre fonctions suivantes :
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 );
Les routines indiquées ci-dessus effectuent les opérations suivantes :
- La routine LONGARR_from_local compte les nœuds de la liste, alloue un objet LONGARR avec la taille(LONGARR) + Count*sizeof(long), définit le champ Size sur Count et copie les données dans le champ DataArr.
- La routine LONGARR_to_local crée une liste avec les nœuds Size et transfère le tableau vers les nœuds appropriés.
- La routine LONGARR_free_inst ne libère rien dans ce cas.
- La routine LONGARR_free_local libère tous les nœuds de la liste.