Boolesche P/Invoke-Argumente mit MarshalAs markieren

Aktualisiert: November 2007

     TypeName

MarkBooleanPInvokeArgumentsWithMarshalAs

CheckId

CA1414

Kategorie

Microsoft.Interoperability

Unterbrechende Änderung

Breaking

Ursache

Eine Deklaration für eine Plattformaufrufmethode enthält einen System.Boolean-Parameter oder -Rückgabewert, allerdings wird das System.Runtime.InteropServices.MarshalAsAttribute-Attribut nicht auf den Parameter oder Rückgabewert angewendet.

Regelbeschreibung

Eine Plattformaufrufmethode greift auf nicht verwalteten Code zu und wird mit dem Declare-Schlüsselwort in Visual Basic oder System.Runtime.InteropServices.DllImportAttribute definiert. MarshalAsAttribute gibt das Marshallingverhalten für die Konvertierung von Datentypen zwischen verwaltetem und nicht verwaltetem Code an. Für viele einfache Datentypen wie System.Byte und System.Int32 ist eine einzige Darstellung in nicht verwaltetem Code vorhanden, und daher muss ihr Marshallingverhalten nicht angegeben werden. Die Common Language Runtime stellt automatisch das richtige Verhalten bereit.

Der Boolean-Datentyp verfügt über mehrere Darstellungen in nicht verwaltetem Code. Wenn MarshalAsAttribute nicht angegeben wird, lautet das standardmäßige Marshallingverhalten für den Boolean-Datentyp UnmanagedType.Bool. Dies ist eine 32-Bit-Ganzzahl, die nicht in jedem Fall geeignet ist. Die für die nicht verwaltete Methode erforderliche boolesche Darstellung sollte ermittelt werden und mit dem entsprechenden System.Runtime.InteropServices.UnmanagedType übereinstimmen. UnmanagedType.Bool ist der Win32-BOOL-Typ, der immer 4 Bytes aufweist. UnmanagedType.U1 sollte für bool in C++ oder für andere 1-Byte-Typen verwendet werden. Weitere Informationen finden Sie unter Standardmäßiges Marshalling für boolesche Typen.

Behandlung von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, wenden Sie MarshalAsAttribute auf den Boolean-Parameter oder -Rückgabewert an. Legen Sie den Wert des Attributs auf den entsprechenden UnmanagedType fest.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie keine Warnung dieser Regel. Auch wenn das standardmäßige Marshallingverhalten geeignet ist, lässt sich der Code sehr viel problemloser verwalten, wenn das Verhalten explizit angegeben wird.

Beispiel

Im folgenden Beispiel werden zwei Plattformaufrufmethoden veranschaulicht, die mit den entsprechenden MarshalAsAttribute-Attributen markiert sind.

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

Verwandte Regeln

Deklarationen von P/Invoke müssen portabel sein

Marshalling für P/Invoke-Zeichenfolgenargumente festlegen

Siehe auch

Konzepte

Standardmäßiges Marshalling für boolesche Typen

Referenz

System.Runtime.InteropServices.UnmanagedType

Weitere Ressourcen

Interaktion mit nicht verwaltetem Code