Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Pour rester indépendantes du langage de programmation, le système COM de Windows et de nombreuses API Windows renvoient un type entier de 4 octets appelé HRESULT, pour indiquer si une API a réussi ou échoué, et fournir des informations sur l’échec. Les autres valeurs qui doivent être transmises à l’appelant sont « retournées » via des paramètres de pointeur qui agissent comme des paramètres « out » et sont généralement le dernier paramètre de la signature. Les langages tels que C# et Visual Basic traduisent traditionnellement un code d’échec en exception pour correspondre à la façon dont les échecs sont généralement propagés dans la langue et s’attendent à ce que les signatures de méthode d’interopérabilité n’incluent pas le HRESULT. Pour traduire la signature de méthode en signature native, le runtime transfère la valeur de retour de la méthode vers un paramètre « out » supplémentaire, avec un niveau d’indirection supplémentaire (c'est-à-dire qu'il en fait un pointeur vers le type de retour de la signature managée), et présuppose une valeur de retour HRESULT. Si la méthode managée retourne void, aucun paramètre supplémentaire n’est ajouté et la valeur de retour devient un HRESULT. Par exemple, consultez les deux méthodes COM C# suivantes qui se traduisent par la même signature native :
int Add(int a, int b);
void Add(int a, int b, out int sum);
HRESULT Add(int a, int b, /* out */ int* sum);
PreserveSig dans COM
Toutes les méthodes COM en C# sont censées utiliser la signature traduite par défaut. Pour utiliser et exporter des méthodes sans traduction de la signature ni gestion des valeurs HRESULT, ajoutez le PreserveSigAttribute à une méthode d’interface COM. Lorsque l’attribut est appliqué à une méthode, aucune traduction n’est effectuée vers la signature, et les exceptions ne sont pas levées pour les valeurs défaillantes HRESULT . Cela s’applique à la fois à COM intégré et à COM généré par la source. Par exemple, consultez la signature de méthode C# suivante avec un PreserveSig attribut et sa signature native correspondante.
[PreserveSig]
int Add(int a, int b, out int sum);
HRESULT Add(int a, int b, int* sum);
Cela peut être utile si la méthode peut retourner différentes HRESULT valeurs qui ne sont pas des échecs, mais doit être gérée différemment. Par exemple, certaines méthodes peuvent renvoyer la valeur S_FALSE lorsqu’une méthode n’échoue pas, mais retourne uniquement des résultats partiels, et S_OK lorsqu’elle retourne tous les résultats.
PreserveSig avec P/Invokes
L’attribut DllImportAttribute a également le bool PreserveSig champ qui fonctionne de la même manière que le PreserveSigAttributechamp , mais est défini par défaut sur true. Pour indiquer que le runtime doit traduire la signature managée et gérer la HRESULT qui est retournée, définissez le champ PreserveSig sur false dans le DllImportAttribute. Par exemple, consultez les signatures suivantes de deux P/Invokes vers la même méthode native : l'une avec PreserveSig défini à la valeur false, et l'autre avec cette option laissée à la valeur par défaut true.
[DllImport("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true, PreserveSig = false)]
public static extern void SHAutoComplete(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);
[DllImport("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true)]
public static extern int SHAutoCompleteHRESULT(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);
Remarque
Les appels P/Invoke générés par la source, qui utilisent le LibraryImportAttribute, n’ont aucun champ PreserveSig. Le code généré suppose toujours que la signature native et gérée est identique. Pour plus d’informations, consultez P/Invokes générés par la source.
Gérer manuellement les HRESULT valeurs
Lors de l'appel d'une méthode PreserveSig qui retourne un HRESULT, vous pouvez utiliser la méthode ThrowExceptionForHR pour lever l'exception correspondante si HRESULT indique un échec. De même, lors de l’implémentation d’une PreserveSig méthode, vous pouvez utiliser la GetHRForException méthode pour retourner celle HRESULT qui indique une valeur correspondante pour l’exception.
Marshaliser les HRESULT en tant que structs
Lorsque vous utilisez une méthode PreserveSig, int est censé être le type managé pour HRESULT. Toutefois, l’utilisation d’un struct personnalisé de 4 octets comme type de retour vous permet de définir des méthodes et des propriétés d’assistance qui peuvent simplifier l’utilisation du HRESULT. Dans le marshaling intégré, cela fonctionne automatiquement. Pour utiliser une structure en tant que int dans la représentation managée de HRESULT dans le marshaling généré par le code source, ajoutez l’attribut MarshalAsAttribute avec Error comme argument. La présence de cet attribut réinterprète les bits de HRESULT comme une structure.