Compartir a través de


CA1414: Marque los argumentos P/Invoke booleanos con MarshalAs

Nombre de tipo

MarkBooleanPInvokeArgumentsWithMarshalAs

Identificador de comprobación

CA1414

Categoría

Microsoft.Interoperability

Cambio problemático

Causa

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

Descripción de la regla

Un método de invocación de plataforma tiene acceso al código no administrado y se define utilizando la palabra clave Declare en Visual Basic o el atributo System.Runtime.InteropServices.DllImportAttribute. MarshalAsAttribute especifica el comportamiento de cálculo de referencias utilizado para convertir los tipos de datos entre administrado y código no administrado. Muchos tipos de datos sencillos, como System.Byte y System.Int32, tienen una sola representación en el código no administrado y no necesitan que se especifique su comportamiento de cálculo de referencias, ya que Common Language Runtime facilita automáticamente el comportamiento correcto.

El tipo de datos Boolean tiene varias representaciones en el código no administrado. Cuando no se especifica MarshalAsAttribute, el comportamiento de cálculo de referencias predeterminado para el tipo de datos Boolean es UnmanagedType.Bool. Éste es un entero de 32 bits, que no es adecuado en todas las circunstancias. Se debería determinar la representación booleana que necesita el método no administrado y hacerla corresponder con el tipo System.Runtime.InteropServices.UnmanagedType adecuado. UnmanagedType.Bool es el tipo BOOL de Win32, que siempre es de 4 bytes. UnmanagedType.U1 se debe utilizar para bool de C++ u otros tipos de 1 byte. Para obtener más información, vea Cálculo de referencias predeterminado para tipos booleanos.

Cómo corregir infracciones

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

Cuándo suprimir advertencias

No suprima las advertencias de esta regla. Aunque el comportamiento de cálculo de referencias predeterminado sea adecuado, resulta más fácil mantener el código cuando se especifica el comportamiento de manera explícita.

Ejemplo

El ejemplo siguiente muestra dos métodos de invocación de plataforma marcados con los atributos MarshalAsAttribute adecuados.

Imports System
Imports System.Runtime.InteropServices

<assembly: ComVisible(False)>
Namespace UsageLibrary

   <ComVisible(True)> _
   Class NativeMethods

      Private Sub New()
      End Sub

      <DllImport("user32.dll", SetLastError := True)> _
      Friend Shared Function MessageBeep(uType As UInt32) _
         As <MarshalAs(UnmanagedType.Bool)> Boolean
      End Function

      <DllImport("mscoree.dll", SetLastError := True)> _
      Friend Shared Function StrongNameSignatureVerificationEx( _
         <MarshalAs(UnmanagedType.LPWStr)> wszFilePath As String, _
         <MarshalAs(UnmanagedType.U1)> fForceVerification As Boolean, _
         <MarshalAs(UnmanagedType.U1)> ByRef pfWasVerified As Boolean) _
         As <MarshalAs(UnmanagedType.U1)> Boolean
      End Function

   End Class

End Namespace
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);
   }
}
using namespace System;
using namespace System::Runtime::InteropServices;

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

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

      [DllImport("mscoree.dll", 
                 CharSet = CharSet::Unicode, 
                 SetLastError = true)]
      [returnvalue: MarshalAs(UnmanagedType::U1)]
      static bool StrongNameSignatureVerificationEx(
         [MarshalAs(UnmanagedType::LPWStr)] String^ wszFilePath,
         [MarshalAs(UnmanagedType::U1)] Boolean fForceVerification,
         [MarshalAs(UnmanagedType::U1)] Boolean^ pfWasVerified);
   };
}

Reglas relacionadas

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

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

Vea también

Referencia

System.Runtime.InteropServices.UnmanagedType

Conceptos

Cálculo de referencias predeterminado para tipos booleanos

Otros recursos

Interoperar con código no administrado