CA1414: marcar argumentos P/Invoke boolianos com MarshalAs

Item Valor
RuleId CA1414
Categoria Microsoft.Interoperability
Alteração da falha Quebra

Causa

Uma declaração de método de invocação de plataforma inclui um parâmetro System.Boolean ou valor retornado, mas o atributo System.Runtime.InteropServices.MarshalAsAttribute não é aplicado ao parâmetro ou valor retornado.

Descrição da regra

Um método de invocação de plataforma acessa o código não gerenciado e é definido usando a palavra-chave Declare no Visual Basic ou no System.Runtime.InteropServices.DllImportAttribute. MarshalAsAttribute especifica o comportamento de marshaling usado para converter tipos de dados entre código gerenciado e não gerenciado. Muitos tipos de dados simples, como System.Byte e System.Int32, têm uma única representação no código não gerenciado e não exigem especificação de seu comportamento de marshaling; o Common Language Runtime fornece automaticamente o comportamento correto.

O tipo de dados Boolean tem várias representações no código não gerenciado. Quando o MarshalAsAttribute não é especificado, o comportamento de marshaling padrão para o tipo de dados Boolean é System.Runtime.InteropServices.UnmanagedType. Esse é um inteiro de 32 bits, o que não é apropriado em todas as circunstâncias. A representação booliana exigida pelo método não gerenciado deve ser determinada e correspondida ao System.Runtime.InteropServices.UnmanagedType apropriado. UnmanagedType.Bool é o tipo BOOL do Win32, que é sempre 4 bytes. UnmanagedType.U1 deve ser usado para C++ bool ou outros tipos de 1 byte.

Como corrigir violações

Para corrigir uma violação dessa regra, aplique MarshalAsAttribute ao parâmetro Boolean ou valor retornado. Defina o valor do atributo como o UnmanagedType apropriado.

Quando suprimir avisos

Não suprima um aviso nessa regra. Mesmo que o comportamento de marshaling padrão seja apropriado, o código é mais facilmente mantido quando o comportamento é especificado de forma explícita.

Exemplo

O exemplo a seguir mostra métodos de invocação de plataforma marcados com os atributos MarshalAsAttribute apropriados.

using System;
using System.Runtime.InteropServices;

[assembly: ComVisible(false)]
namespace InteroperabilityLibrary
{
   [ComVisible(true)]
   internal class NativeMethods
   {
      private NativeMethods() {}

      [DllImport("user32.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      internal static extern Boolean MessageBeep(UInt32 uType);

      [DllImport("mscoree.dll", 
                 CharSet = CharSet.Unicode, 
                 SetLastError = true)]
      [return: MarshalAs(UnmanagedType.U1)]
      internal static extern bool StrongNameSignatureVerificationEx(
         [MarshalAs(UnmanagedType.LPWStr)] string wszFilePath,
         [MarshalAs(UnmanagedType.U1)] bool fForceVerification,
         [MarshalAs(UnmanagedType.U1)] out bool pfWasVerified);
   }
}

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

CA2101: especificar marshaling para argumentos de cadeia de caracteres P/Invoke

Confira também