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

更新:2007 年 11 月

TypeName

PInvokeDeclarationsShouldBePortable

CheckId

CA1901

类别

Microsoft.Portability

是否重大更改

Breaking - 如果 P/Invoke 在程序集外可见。Non Breaking - 如果 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 参数被声明为 IntPtr,它在 32 位平台上为 4 字节宽,在 64 位平台上为 8 字节宽。在后面的非托管声明中,您可以看到 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);
}

请参见

其他资源

可移植性警告