Partager via


Conventions de codage pour l'API de métadonnées

Cette rubrique présente les conventions de codage utilisées par l'API de métadonnées.

Gestion des paramètres de chaîne

L'API de métadonnées expose toutes les chaînes au format Unicode. (Les noms de symboles sur le disque sont en fait au format UTF-8, mais ce format est masqué pour les clients API de métadonnées.) Chaque chaîne retournée est un triple de trois paramètres (les noms de paramètres réels varient) :

  • [in] ULONG cchString - Taille, en octets, de la mémoire tampon dans laquelle la chaîne, y compris le caractère null de fin, doit être retournée.

  • [out] LPCWSTR wzString - Pointeur vers la mémoire tampon dans laquelle la chaîne est retournée.

  • [out] ULONG *pchString - Pointeur vers la taille de la chaîne retournée (y compris le caractère null de fin). Si la mémoire tampon est trop petite pour stocker la chaîne complète, la chaîne retournée est tronquée, une indication d'erreur est retournée, et le client peut réallouer la mémoire tampon et réessayer si besoin est.

Noms de symboles

Les conventions suivantes s'appliquent aux noms de symboles pour les paramètres de chaîne :

  • Les paramètres de chaîne qui sont des noms de symboles sont toujours supposés se terminer par le caractère NULL, et aucun paramètre de longueur [in] n'est requis. Les caractères null incorporés ne sont pas pris en charge.

  • Si une chaîne de paramètre [in] est trop grande pour être conservée sans être tronquée, une erreur sera retournée.

Chaînes utilisateur

Les conventions suivantes s'appliquent aux paramètres de chaîne fournis par l'utilisateur :

  • Les chaînes utilisateur peuvent avoir des caractères null incorporés et ne doivent pas avoir de marque de fin null.

  • Une longueur doit être fournie dans le paramètre cchString. La taille de la mémoire tampon doit être la longueur exacte de la chaîne qui sera stockée.

Stockage des valeurs par défaut

Les constantes peuvent être stockées dans des métadonnées en tant que valeurs par défaut pour les champs, les paramètres et les propriétés. Trois paramètres sont utilisés pour spécifier une constante (les noms de paramètres réels varient) :

  • [in] DWORD dwCPlusTypeFlag - Valeur de l'énumération CorElementType qui spécifie le type de la valeur par défaut.

  • [in] void const *pValue - Pointeur vers la valeur par défaut réelle. Par exemple, un pointeur vers la valeur DWORD de 4 octets contenant 0x0000002A stockera une valeur DWORD de 42 décimales dans les métadonnées. La valeur par défaut ne peut avoir pour type (spécifié dans dwCPlusTypeFlag) que primitif ou chaîne. Si dwCPlusTypeFlag correspond à ELEMENT_TYPE_CLASS, la valeur par défaut sera null.

  • [in] ULONG cchValue - Nombre de caractères Unicode dans la séquence d'octets vers laquelle pValue pointe. Ce paramètre est requis uniquement si le type, spécifié dans dwCPlusTypeFlag, est ELEMENT_TYPE_STRING. Dans tous les autres cas, la longueur est déduite du type.

Les valeurs par défaut ne sont pas insérées automatiquement dans le code d'initialisation ou dans les zones des données initialisées statiquement. Elles sont simplement enregistrées dans les métadonnées.

Pour indiquer que vous ne souhaitez pas spécifier une valeur par défaut, définissez tous les bits de dwCPlusTypeFlag (autrement dit, affectez -1 à la valeur).

Pointeurs null pour les paramètres de retour

Dans la mesure où les API de métadonnées exécutent une vérification des erreurs minimum, elles attendent un pointeur non null pour les paramètres de retour dans les circonstances suivantes :

  • Dans les méthodes Define, un pointeur non null est requis pour le jeton retourné. Ces méthodes créent l'élément que vous souhaitez définir et retournent un jeton pour l'élément. Vous pouvez choisir d'ignorer le jeton si vous n'en avez pas besoin.

  • Les méthodes Find retournent toujours le jeton pour l'élément s'il est trouvé.

  • Dans les méthodes Get, vous pouvez passer null dans les paramètres dont vous n'avez plus besoin.

  • Dans les méthodes Set, il n'y a généralement aucune valeur de retour. Passez le jeton pour l'élément à mettre à jour, ainsi que les valeurs à mettre à jour, et ces méthodes exécutent la mise à jour.

Valeurs de paramètre à ignorer

Plusieurs méthodes dans l'API de métadonnées vous permettent de modifier les propriétés d'un élément qui a été défini précédemment. L'exemple suivant utilise la méthodeIMetaDataEmit::SetFieldProps pour modifier les propriétés d'un champ qui ont été préalablement fournies dans un appel à IMetaDataEmit::DefineField :

HRESULT SetFieldProps(mdFieldDef fd, DWORD dwFieldFlags,
        DWORD dwDefType, void const *pValue, ULONG cchValue)

Parfois, vous souhaitez peut-être modifier dwFieldFlags mais pas pValue (ou vice versa). Dans ce cas, vous devez passer une valeur de paramètre pour éviter une erreur, même si vous ne souhaitez pas modifier cette valeur. Vous pouvez toutefois passer une valeur particulière indiquant que l'argument doit être ignoré si vous ne souhaitez pas modifier sa valeur. Les API de métadonnées utilisent les conventions suivantes pour indiquer qu'un argument de méthode doit être ignoré :

  • Si le paramètre est un type pointeur, passez un pointeur null.

  • Si le paramètre est un type valeur (en général, un masque de bits d'indicateurs), passez une valeur de tous les bits définis (-1).

Retours en cas d'erreur

Presque toutes les méthodes figurant dans les interfaces IMetaDataDispenserEx, IMetaDataEmit et IMetaDataImport retournent une valeur HRESULT pour indiquer leur résultat. Le résultat a la valeur S_OK si l'opération a réussi. En cas d'échec de l'appel, il retourne une autre valeur pour décrire la raison de l'échec de l'opération.

Selon un modèle général appliqué à toutes les API de métadonnées, si l'appelant fournit une mémoire tampon de chaîne trop petite pour contenir les résultats, les API copient le nombre de caractères qu'elle peut contenir, mais elles retournent la valeur HRESULT de CLDB_S_TRUNCATION au lieu de S_OK.

Les appelants des interfaces IMetadata sont des compilateurs ou des outils. Il est important que ces appelants vérifient toujours l'état de retour de chaque appel pour détecter les erreurs. Dans ces cas, les conditions d'erreur font apparaître un problème du côté de l'appelant direct (compilateur, par exemple) plutôt que du côté de l'utilisateur (programme d'application, par exemple).

Gestion de la mémoire

La valeur par défaut COM générique est la suivante : l'appelant libère la mémoire allouée par l'appelé. Les méthodes de métadonnées fonctionnent toutefois différemment.

De nombreuses méthodes de métadonnées retournent des pointeurs [out] vers les blocs de mémoire. Cette mémoire fait partie du tas de métadonnées du module et appartient au Common Language Runtime (CLR). Par conséquent, un pointeur vous est directement attribué dans le stockage en mémoire du CLR des métadonnées et votre application n'est pas tenue de libérer de la mémoire.

Prise en charge des génériques

Dans le .NET Framework version 2.0, les API de métadonnées ont été considérablement étendues pour prendre en charge les génériques (ce que l'on appelle parfois aussi « polymorphisme paramétrique »). Les génériques ressemblent aux modèles C++. Voici un exemple de définition de classe générique en C# :

public class Dictionary<Key, Val> { . . . }

Dans ce cas, la classe Dictionary est paramétrée avec deux paramètres génériques nommés Key et Val. Lorsque la classe est instanciée, l'utilisateur sélectionne des types pour les paramètres génériques, comme dans l'exemple suivant :

Dictionary<string, int> NameToPhone = new Dictionary<string, int>();
Dictionary<int, string> PhoneToName = new Dictionary<int, string>();

Voir aussi

Concepts

Vue d'ensemble des métadonnées