CA1414:用 MarshalAs 标记布尔型 P/Invoke 参数

类型名

MarkBooleanPInvokeArgumentsWithMarshalAs

CheckId

CA1414

类别

Microsoft.Interoperability

是否重大更改

原因

平台调用方法声明包括一个 System.Boolean 参数或返回值,但是未将 System.Runtime.InteropServices.MarshalAsAttribute 特性应用于该参数或返回值。

规则说明

平台调用方法访问非托管代码,而且是使用 Visual Basic 中的 Declare 关键字或使用 System.Runtime.InteropServices.DllImportAttribute 定义的。 MarshalAsAttribute 指定用于在托管代码与非托管代码之间转换数据类型的封送处理行为。 许多简单数据类型(如 System.ByteSystem.Int32)在托管代码中都只有一种表示形式,无需为它们指定封送处理行为;公共语言运行时会自动提供正确的行为。

Boolean 数据类型在非托管代码中有多种表示形式。 当未指定 MarshalAsAttribute 时,Boolean 数据类型的默认封送处理行为是 UnmanagedType.Bool。 这是 32 位整数,并不适用于所有情况。 应当确定非托管方法所需的布尔表示形式并将其与相应的 System.Runtime.InteropServices.UnmanagedType 匹配。 UnmanagedType.Bool 是 Win32 BOOL 类型,它总是为 4 个字节。 UnmanagedType.U1 应当用于 C++ bool 或其他单字节类型。 有关更多信息,请参见 布尔类型的默认封送处理

如何解决冲突

若要修复与该规则的冲突,请将 MarshalAsAttribute 应用于 Boolean 参数或返回值。 将该特性的值设置为相应的 UnmanagedType

何时禁止显示警告

不要禁止显示此规则发出的警告。 显式指定此行为会使代码更易于维护,即使默认封送处理行为适用也是如此。

示例

下面的示例演示两个标记有相应 MarshalAsAttribute 特性的平台调用方法。

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

相关规则

CA1901:P/Invoke 声明应为可移植声明

CA2101:指定对 P/Invoke 字符串参数进行封送处理

请参见

参考

System.Runtime.InteropServices.UnmanagedType

概念

布尔类型的默认封送处理

其他资源

与非托管代码交互操作