CA1414: Mark boolean P/Invoke arguments with MarshalAs

 

For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.

For the latest documentation on Visual Studio 2017, see CA1414: Mark boolean P-Invoke arguments with MarshalAs on docs.microsoft.com.

TypeNameMarkBooleanPInvokeArgumentsWithMarshalAs
CheckIdCA1414
CategoryMicrosoft.Interoperability
Breaking ChangeBreaking

A platform invoke method declaration includes a System.Boolean parameter or return value but the System.Runtime.InteropServices.MarshalAsAttribute attribute is not applied to the parameter or return value.

A platform invoke method accesses unmanaged code and is defined by using the Declare keyword in Visual Basic or the System.Runtime.InteropServices.DllImportAttribute. MarshalAsAttribute specifies the marshaling behavior that is used to convert data types between managed and unmanaged code. Many simple data types, such as System.Byte and System.Int32, have a single representation in unmanaged code and do not require specification of their marshaling behavior; the common language runtime automatically supplies the correct behavior.

The Boolean data type has multiple representations in unmanaged code. When the MarshalAsAttribute is not specified, the default marshaling behavior for the Boolean data type is UnmanagedType.Bool. This is a 32-bit integer, which is not appropriate in all circumstances. The Boolean representation that is required by the unmanaged method should be determined and matched to the appropriate System.Runtime.InteropServices.UnmanagedType. UnmanagedType.Bool is the Win32 BOOL type, which is always 4 bytes. UnmanagedType.U1 should be used for C++ bool or other 1-byte types. For more information, see Default Marshaling for Boolean Types.

To fix a violation of this rule, apply MarshalAsAttribute to the Boolean parameter or return value. Set the value of the attribute to the appropriate UnmanagedType.

Do not suppress a warning from this rule. Even if the default marshaling behavior is appropriate, the code is more easily maintained when the behavior is explicitly specified.

The following example shows two platform invoke methods that are marked with the appropriate MarshalAsAttribute attributes.

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

CA1901: P/Invoke declarations should be portable

CA2101: Specify marshaling for P/Invoke string arguments

System.Runtime.InteropServices.UnmanagedType
Default Marshaling for Boolean Types
Interoperating with Unmanaged Code

Show: