CA1901: объявления P/Invoke должны быть переносимыми

Товар Значение
Идентификатор правила CA1901
Категория Microsoft.Portability
Критическое изменение Критическое— если P/Invoke отображается вне сборки. Если P/Invoke не отображается вне сборки.

Причина

Это правило оценивает размер каждого параметра и возвращаемое значение P/Invoke и проверяет правильность их размера, когда маршалируется в неуправляемый код на 32-разрядных и 64-разрядных платформах. Наиболее распространенное нарушение этого правила заключается в передаче целого числа фиксированного размера, в котором требуется переменная, зависящая от платформы, размер указателя.

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

Любой из следующих сценариев нарушает это правило:

  • Возвращаемое значение или параметр вводится в виде целого числа фиксированного размера, когда оно должно быть введено как целое IntPtrчисло.

  • Возвращаемое значение или параметр вводится в качестве IntPtr типа, когда оно должно быть введено в виде целого числа фиксированного размера.

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

Это нарушение можно исправить с помощью IntPtr или UIntPtr представления дескрипторов вместо Int32 него UInt32.

Когда лучше отключить предупреждения

Не следует отключать это предупреждение.

Пример

В следующем примере показано нарушение этого правила.

internal class NativeMethods
{
    [DllImport("shell32.dll", CharSet=CharSet.Auto)]
    internal static extern IntPtr ExtractIcon(IntPtr hInst,
        string lpszExeFileName, IntPtr nIconIndex);
}

В этом примере nIconIndex параметр объявляется как IntPtr4 байта, широкий на 32-разрядной платформе и 8 байтов на 64-разрядной платформе. В неуправляемом объявлении, которое следует, можно увидеть, что nIconIndex 4-байтовое целое число без знака на всех платформах.

HICON ExtractIcon(HINSTANCE hInst, LPCTSTR lpszExeFileName,
    UINT nIconIndex);

Чтобы устранить нарушение, измените объявление на следующее:

internal class NativeMethods{
    [DllImport("shell32.dll", CharSet=CharSet.Auto)]
    internal static extern IntPtr ExtractIcon(IntPtr hInst,
        string lpszExeFileName, uint nIconIndex);
}