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