Поделиться через


CA1414: пометьте логические аргументы P/Invoke с помощью атрибута MarshalAs

TypeName

MarkBooleanPInvokeArgumentsWithMarshalAs

CheckId

CA1414

Категория

Microsoft.Interoperability

Критическое изменение

Критическое изменение

Причина

Объявление метода вызова неуправляемого кода содержит параметр или возвращаемое значение типа Boolean, однако к этому параметру или возвращаемому значению не применяется атрибут MarshalAsAttribute.

Описание правила

Метод вызова платформы получает доступ к неуправляемому коду и определяется с помощью ключевого слова Declare в Visual Basic или DllImportAttribute.MarshalAsAttribute задает поведение маршалинга, используемое для преобразования типов данных между управляемым и неуправляемым кодом.Многие простые типы данных, такие как Byte и Int32, имеют единственное представление в неуправляемом коде, и для них не требуется указывать поведение маршалинга; среда CLR автоматически предоставляет правильное поведение.

Тип данных Boolean имеет несколько представлений в неуправляемом коде.Если атрибут MarshalAsAttribute не указан, поведение маршалинга, используемое по умолчанию, состоит в преобразовании типа данных Boolean в тип UnmanagedType.Bool.Это 32-разрядный целочисленный тип, который можно использовать далеко не во всех случаях.Необходимо определить представление типа Boolean, требуемое для неуправляемого метода, и сопоставить его соответствующему значению UnmanagedType.Значение UnmanagedType.Bool представляет собой тип BOOL для системWin32, который всегда имеет размер 4 байта.Для типа bool языка C++ и других однобайтовых типов следует использовать значение UnmanagedType.U1.Для получения дополнительной информации см. Маршалинг по умолчанию для логических типов.

Устранение нарушений

Чтобы устранить нарушение данного правила, примените атрибут 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

См. также

Ссылки

UnmanagedType

Основные понятия

Маршалинг по умолчанию для логических типов

Другие ресурсы

Взаимодействие с неуправляемым кодом