Partager via


Techniques IDL pour une meilleure conception d’interface et de méthode

Envisagez d’utiliser les techniques spécifiques à IDL suivantes pour améliorer la sécurité et les performances lorsque vous développez des interfaces et des méthodes RPC qui gèrent les données conformes et variant. Les attributs référencés dans cette rubrique sont les attributs IDL définis sur les paramètres de méthode qui gèrent les données conformes (par exemple, les attributs [size_is] et [max_is] ) ou les données variant (par exemple, les attributs [length_is] et [chaîne] attributs).

Utilisation de l’attribut [range] avec des paramètres de données conformes

L’attribut [plage] indique à l’exécution RPC d’effectuer une validation de taille supplémentaire pendant le processus de démarshalation des données. Plus précisément, il vérifie que la taille fournie des données transmises en tant que paramètre associé se trouve dans la plage spécifiée.

L’attribut [plage] n’affecte pas le format de câble.

Si la valeur sur le câble est en dehors de la plage autorisée, RPC lève une exception RPC_X_INVALID_BOUND ou RPC_X_BAD_STUB_DATA. Cela fournit un niveau supplémentaire de validation des données et peut aider à empêcher les erreurs de sécurité courantes telles que les dépassements de mémoire tampon. De même, l’utilisation de [plage] peut améliorer les performances de l’application, car les données conformes marquées avec elles ont des contraintes clairement définies à prendre en compte par le service RPC.

Règles de gestion de la mémoire stub du serveur RPC

Il est important de comprendre les règles de gestion de mémoire stub du serveur RPC lors de la création des fichiers IDL pour une application compatible RPC. Les applications peuvent améliorer l’utilisation des ressources du serveur à l’aide de [plage] conjointement avec les données conformes comme indiqué ci-dessus, ainsi que d’éviter délibérément l’application d’attributs IDL de données de longueur variable tels que [length_is] pour les données conformes.

L’application de [length_is] aux champs de structure de données définis dans un fichier IDL n’est pas recommandée.

Meilleures pratiques pour les paramètres de données de longueur variable

Voici plusieurs bonnes pratiques à prendre en compte lors de la définition des attributs IDL pour les structures de données de taille variable, les paramètres de méthode et les champs.

  • Utilisez la corrélation anticipée. Il est généralement préférable de définir le paramètre de taille variable ou le champ de sorte qu’il se produise immédiatement après le type intégral de contrôle.

    Par exemple

    earlyCorr
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long size, 
    [in,size_is(size)] char *pv
    );
    

    est mieux que

    lateCorr
    (
    [in,size_is(size)] char *pv, 
    [in, range(MIN_COUNT, MAX_COUNT)] long size)
    );
    

    wherein earlyCorr déclare le paramètre de taille immédiatement avant le paramètre de données de longueur variable, et lateCorr déclare le paramètre de taille après celui-ci. L’utilisation de la correspondance précoce améliore les performances globales, en particulier dans les cas où la méthode est appelée fréquemment.

  • Pour les paramètres marqués avec [out, size_is] tuple d’attribut et où la longueur des données est connue côté client ou où le client a une limite supérieure raisonnable, la définition de méthode doit être similaire à ce qui suit en termes d’attribution et de séquence de paramètres :

    outKnownSize
    (
    [in,range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out,size_is(lSize)] UserDataType * pArr
    );
    

    Dans ce cas, le client fournit une mémoire tampon de taille fixe pour pArr, ce qui permet au service RPC côté serveur d’allouer une mémoire tampon raisonnablement dimensionnée avec un bon degré d’assurance. Notez que dans l’exemple, les données sont reçues du serveur ([out]). La définition est similaire pour les données transmises au serveur ([dans]).

  • Dans les cas où le composant côté serveur d’une application RPC décide de la longueur des données, la définition de méthode doit être similaire à ce qui suit :

    typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG;
    
    outUnknownSize
    (
    [out] RANGED_LONG *pSize,
    [out,size_is(,*pSize)] UserDataType **ppArr
    );
    

    RANGED_LONG est un type défini pour les stubs client et serveur, et d’une taille spécifiée que le client peut anticiper correctement. Dans l’exemple, le client passe ppArr en tant que NULL, et le composant d’application serveur RPC alloue la quantité de mémoire correcte. Lors du retour, le service RPC côté client alloue la mémoire pour les données retournées.

  • Si le client souhaite envoyer un sous-ensemble d’un grand tableau conforme au serveur, l’application peut spécifier la taille du sous-ensemble comme illustré dans l’exemple suivant :

    inConformantVaryingArray
    (
    [in,range(MIN_COUNT,MAX_COUNT)] long lSize,
    [in] long lLength, 
    [in,size_is(lSize), length_is(lLength)] UserDataType *pArr
    );
    

    De cette façon, RPC transmet uniquement lLength éléments du tableau sur le fil. Toutefois, cette définition force le service RPC à allouer la mémoire de taille lSize côté serveur.

  • Si le composant d’application cliente détermine la taille maximale d’un tableau que le serveur peut retourner, mais permet au serveur de transmettre un sous-ensemble de ce tableau, l’application peut spécifier ce comportement en définissant l’IDL comme dans l’exemple suivant :

    inMaxSizeOutLength
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out] long *pLength,
    [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr
    );
    

    Le composant d’application cliente spécifie la taille maximale du tableau et le serveur spécifie le nombre d’éléments qu’il transmet au client.

  • Si le composant d’application serveur doit retourner une chaîne au composant d’application cliente et si le client connaît la taille maximale à retourner du serveur, l’application peut utiliser un type de chaîne conforme, comme illustré dans l’exemple suivant :

    outStringKnownSize
    (
    [in,range(MIN_COUNT, MAX_STRING)] long lSize,
    [out,size_is(lSize),string] wchar_t *pString
    );
    
  • Si le composant d’application cliente ne doit pas contrôler la taille de la chaîne, le service RPC peut allouer spécifiquement la mémoire, comme illustré dans l’exemple suivant :

    outStringUnknownSize
    (
    [out] LPWSTR *ppStr
    );
    

    Le composant d’application cliente doit définir ppStr sur NULL lors de l’appel de la méthode RPC.