CA1901: P/Invoke declarations should be portable
Applies to: Visual Studio Visual Studio for Mac
Note
This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
Item | Value |
---|---|
RuleId | CA1901 |
Category | Microsoft.Portability |
Breaking change | Breaking - If the P/Invoke is visible outside the assembly. Non-breaking - If the P/Invoke is not visible outside the assembly. |
Cause
This rule evaluates the size of each parameter and the return value of a P/Invoke and verifies that their size, when marshaled to unmanaged code on 32-bit and 64-bit platforms, is correct. The most common violation of this rule is to pass a fixed-sized integer where a platform-dependent, pointer-sized variable is required.
Rule description
Either of the following scenarios violates this rule occurs:
The return value or parameter is typed as a fixed-size integer when it should be typed as an
IntPtr
.The return value or parameter is typed as an
IntPtr
when it should be typed as a fixed-size integer.
How to fix violations
You can fix this violation by using IntPtr
or UIntPtr
to represent handles instead of Int32
or UInt32
.
When to suppress warnings
You should not suppress this warning.
Example
The following example demonstrates a violation of this rule.
internal class NativeMethods
{
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
internal static extern IntPtr ExtractIcon(IntPtr hInst,
string lpszExeFileName, IntPtr nIconIndex);
}
In this example, the nIconIndex
parameter is declared as an IntPtr
, which is 4 bytes wide on a 32-bit platform and 8 bytes wide on a 64-bit platform. In the unmanaged declaration that follows, you can see that nIconIndex
is a 4-byte unsigned integer on all platforms.
HICON ExtractIcon(HINSTANCE hInst, LPCTSTR lpszExeFileName,
UINT nIconIndex);
To fix the violation, change the declaration to the following:
internal class NativeMethods{
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
internal static extern IntPtr ExtractIcon(IntPtr hInst,
string lpszExeFileName, uint nIconIndex);
}