CA1901 : Les déclarations P/Invoke doivent être portables

Élément Valeur
ID de la règle CA1901
Category Microsoft.Portability
Modification avec rupture Cassant : si P/Invoke est visible en dehors de l’assembly. Non cassant : si P/Invoke n’est pas visible en dehors de l’assembly.

Cause

Cette règle évalue la taille de chaque paramètre et la valeur de retour d’un P/Invoke, puis vérifie si la taille est correcte quand elle est marshalée au code non managé sur des plateformes 32 bits et 64 bits. La violation la plus courante de cette règle consiste à transmettre un entier de taille fixe où une variable de la taille du pointeur dépendante de la plateforme est requise.

Description de la règle

L’un des scénarios suivants enfreint cette règle :

  • La valeur renvoyée ou le paramètre renvoyé est tapé comme un entier de taille fixe alors qu’il doit être tapé en tant que IntPtr.

  • La valeur renvoyée ou le paramètre renvoyé est tapé en tant que IntPtr alors qu’il doit être tapé comme un entier de taille fixe.

Comment corriger les violations

Vous pouvez corriger cette violation en utilisant IntPtr ou UIntPtr pour représenter des descripteurs au lieu de Int32 ou UInt32.

Quand supprimer les avertissements

Vous ne devez pas supprimer cet avertissement.

Exemple

L’exemple suivant illustre une violation de cette règle.

internal class NativeMethods
{
    [DllImport("shell32.dll", CharSet=CharSet.Auto)]
    internal static extern IntPtr ExtractIcon(IntPtr hInst,
        string lpszExeFileName, IntPtr nIconIndex);
}

Dans cet exemple, le paramètre nIconIndex est déclaré en tant que IntPtr, qui est de 4 octets de large sur une plateforme 32 bits et de 8 octets de large sur une plateforme 64 bits. Dans la déclaration non managée qui suit, vous pouvez voir que nIconIndex est un entier non signé de 4 octets sur toutes les plateformes.

HICON ExtractIcon(HINSTANCE hInst, LPCTSTR lpszExeFileName,
    UINT nIconIndex);

Pour corriger la violation, remplacez la déclaration par les éléments suivants :

internal class NativeMethods{
    [DllImport("shell32.dll", CharSet=CharSet.Auto)]
    internal static extern IntPtr ExtractIcon(IntPtr hInst,
        string lpszExeFileName, uint nIconIndex);
}