CA1414: Marque los argumentos P/Invoke booleanos con MarshalAs

Elemento Valor
RuleId CA1414
Category Microsoft.Interoperability
Cambio importante Problemático

Causa

Una declaración del método de invocación de plataforma incluye un parámetro System.Boolean o un valor devuelto, pero el atributo System.Runtime.InteropServices.MarshalAsAttribute no se aplica al parámetro ni al valor devuelto.

Descripción de la regla

Un método de invocación de plataforma accede al código no administrado y se define mediante la palabra clave Declare en Visual Basic o System.Runtime.InteropServices.DllImportAttribute. MarshalAsAttribute especifica el comportamiento de la serialización que se usa para convertir tipos de datos entre código administrado y no administrado. Muchos tipos de datos simples, como System.Byte y System.Int32, tienen una sola representación en código no administrado y no requieren especificación de su comportamiento de serialización; Common Language Runtime proporciona automáticamente el comportamiento correcto.

El tipo de datosBoolean tiene varias representaciones en código no administrado. Cuando MarshalAsAttribute no se especifica, el comportamiento de serialización predeterminado para el tipo de datos Boolean es System.Runtime.InteropServices.UnmanagedType. Se trata de un entero de 32 bits, lo que no es adecuado en todas las circunstancias. Debe determinarse la representación booleana que requiere el método no administrado y debe coincidir con la adecuada System.Runtime.InteropServices.UnmanagedType. UnmanagedType.Bool es el tipo BOOL Win32, que siempre es de 4 bytes. UnmanagedType.U1 debe usarse para C++ bool u otros tipos de 1 byte.

Cómo corregir infracciones

Para corregir cualquier infracción de esta regla, aplique MarshalAsAttribute al parámetro Boolean o al valor devuelto. Establezca el valor del atributo en el adecuado UnmanagedType.

Cuándo suprimir las advertencias

No suprima las advertencias de esta regla. Aunque si el comportamiento predeterminado de la serialización sea adecuado, el código se mantiene más fácilmente cuando el comportamiento se especifica explícitamente.

Ejemplo

En el ejemplo siguiente se muestran los métodos de invocación de plataforma marcados con los atributos MarshalAsAttribute adecuados.

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: Las declaraciones P/Invoke deben ser portables

CA2101: Especifique cálculo de referencias para argumentos de cadena P/Invoke

Vea también