Condividi tramite


CA1414: Contrassegnare gli argomenti P/Invoke booleani con MarshalAs

TypeName

MarkBooleanPInvokeArgumentsWithMarshalAs

CheckId

CA1414

Category

Microsoft.Interoperability

Breaking Change

Breaking

Causa

Una dichiarazione di metodo di platform invoke include un valore restituito o un parametro System.Boolean, a cui tuttavia non viene applicato l'attributo System.Runtime.InteropServices.MarshalAsAttribute.

Descrizione della regola

Un metodo di platform invoke accede al codice non gestito e viene definito mediante la parola chiave Declare in Visual Basic o mediante System.Runtime.InteropServices.DllImportAttribute. MarshalAsAttribute specifica il comportamento di marshalling utilizzato per convertire i tipi di dati tra codice gestito e non gestito. Molti tipi di dati semplici quali System.Byte e System.Int32, offrono una rappresentazione singola in codice non gestito e non richiedono la specifica del relativo comportamento di marshalling. Common Language Runtime fornisce automaticamente il funzionamento corretto.

Per il tipo di dati Boolean sono disponibili più rappresentazioni nel codice non gestito. Quando MarshalAsAttribute non è specificato, il comportamento di marshalling predefinito per il tipo di dati Boolean è UnmanagedType.Bool. Si tratta di un Integer a 32 bit, che non è appropriato in tutte le circostante. La rappresentazione booleana richiesta dal metodo non gestito dovrebbe essere determinata e messa in corrispondenza con l'oggetto System.Runtime.InteropServices.UnmanagedType appropriato. UnmanagedType.Bool è il tipo BOOL Win32, che è sempre pari a 4 byte. UnmanagedType.U1 dovrebbe essere utilizzato per C++ bool o altri tipi a 1 byte. Per ulteriori informazioni, vedere Marshalling predefinito per i tipi boolean.

Come correggere le violazioni

Per correggere una violazione di questa regola, applicare MarshalAsAttribute al valore restituito o al parametro Boolean. Impostare il valore dell'attributo sull'oggetto UnmanagedType appropriato.

Esclusione di avvisi

Non escludere un avviso da questa regola. Anche se il comportamento di marshalling predefinito è appropriato, il codice viene gestito più facilmente quando il comportamento è specificato in modo esplicito.

Esempio

Nell'esempio riportato di seguito sono illustrati due metodi di platform invoke contrassegnati dagli attributi MarshalAsAttribute appropriati.

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);
   };
}

Regole correlate

CA1901: Le dichiarazioni P/Invoke devono essere portabili

CA2101: Specificare il marshalling per gli argomenti di stringa P/Invoke

Vedere anche

Riferimenti

System.Runtime.InteropServices.UnmanagedType

Concetti

Marshalling predefinito per i tipi boolean

Altre risorse

Interoperabilità con codice non gestito