CA1901: Las declaraciones P/Invoke deben ser portátiles

Elemento Valor
RuleId CA1901
Category Microsoft.Portability
Cambio importante Problemático: si P/Invoke es visible fuera del ensamblado. Poco problemático: si P/Invoke no es visible fuera del ensamblado.

Causa

Esta regla evalúa el tamaño de cada parámetro y el valor devuelto de P/Invoke, y comprueba que el tamaño sea correcto al serializar para su conversión en código no administrado en plataformas de 32 y 64 bits. La infracción más común de esta regla es pasar un entero de tamaño fijo en el que se requiere una variable de tamaño de puntero dependiente de la plataforma.

Descripción de la regla

Se produce cualquiera de los escenarios siguientes que infringen esta regla:

  • El valor devuelto o el parámetro se escriben como un entero de tamaño fijo cuando se debe escribir como IntPtr.

  • El valor devuelto o el parámetro se escriben como IntPtr cuando se debe escribir como un entero de tamaño fijo.

Cómo corregir infracciones

Puede corregir esta infracción mediante IntPtr o UIntPtr para representar identificadores en lugar de Int32 o UInt32.

Cuándo suprimir las advertencias

No debe suprimir esta advertencia.

Ejemplo

En el ejemplo siguiente se muestra una infracción de esta regla.

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

En este ejemplo, el parámetro nIconIndex se declara como IntPtr, que tiene 4 bytes de ancho en una plataforma de 32 bits y 8 bytes de ancho en una plataforma de 64 bits. En la declaración no administrada siguiente, puede ver que nIconIndex es un entero sin signo de 4 bytes en todas las plataformas.

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

Para corregir la infracción, cambie la declaración por lo siguiente:

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