CA1901: as declarações de P/Invoke devem ser portáteis

Item Valor
RuleId CA1901
Categoria Microsoft.Portability
Alteração da falha Com interrupção – se o P/Invoke estiver visível fora do assembly. Sem interrupção – se o P/Invoke não estiver visível fora do assembly.

Causa

Essa regra avalia o tamanho de cada parâmetro e o valor de retorno de um P/Invoke, e verifica se o tamanho, durante a realização de marshaling para código não gerenciado em plataformas 32 e 64 bits, está correto. A violação mais comum dessa regra é passar um número inteiro de tamanho fixo que precisa de uma variável de tamanho de ponteiro dependente da plataforma.

Descrição da regra

Qualquer um dos seguintes cenários viola essa regra:

  • O valor ou parâmetro retornado é digitado como um número inteiro de tamanho fixo quando deve ser digitado como um IntPtr.

  • O valor ou parâmetro retornado é digitado como IntPtr quando deve ser digitado como um número inteiro de tamanho fixo.

Como corrigir violações

Você pode corrigir essa violação usando IntPtr ou UIntPtr para representar identificadores em vez de Int32 ou UInt32.

Quando suprimir avisos

Você não deve suprimir este aviso.

Exemplo

O exemplo a seguir demonstra uma violação dessa regra.

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

Neste exemplo, o parâmetro nIconIndex é declarado como um IntPtr, que tem 4 bytes de largura em uma plataforma de 32 bits e 8 bytes de largura em uma plataforma de 64 bits. Na declaração não gerenciada a seguir, você pode ver que nIconIndex é um número inteiro sem sinal de 4 bytes em todas as plataformas.

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

Para corrigir a violação, altere a declaração para o seguinte:

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