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
См. также
Ссылки
Основные понятия
Маршалинг по умолчанию для логических типов