How do I solve this "P/Invoke declarations should be portable"?
c#, pinvoke
Solution
The MSDN page that the warning refers to is the documentation of the native function `SHGetFileInfo`. It gives the signature as:
DWORD_PTR SHGetFileInfo(
__in LPCTSTR pszPath,
DWORD dwFileAttributes,
__inout SHFILEINFO *psfi,
UINT cbFileInfo,
UINT uFlags
);
So the first warning is referring to the fact that `DWORD_PTR` is a pointer sized unsigned integer. That means you should use `UIntPtr`.
The next thing that jumps out is that the `SHFILEINFO` struct is indicated as `__inout`. That means you need to pass it by `ref`.
So the p/invoke declaration should be:
[DllImport("shell32", CharSet=CharSet.Unicode)]
private static extern UIntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint flags
);
The final warning is simple to resolve. Simply place your p/invoke declaration inside a class named `NativeMethods`.
Problem
This code: ``` [DllImport("shell32", CharSet=CharSet.Unicode)] private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags); ``` Causes the following Code Analysis problem: CA1901 P/Invoke declarations should be portable As it is declared in your code, the return type of P/Invoke 'IconUtil.SHGetFileInfo(string, uint, out IconUtil.SHFILEINFO, uint, uint)' will be 4 bytes wide on 64-bit platforms. This is not correct, as the actual native declaration of this API indicates it should be 8 bytes wide on 64-bit platforms. Consult the MSDN Platform SDK documentation for help determining what data type should be used instead of 'int'. What am I supposed to do? I tried "consulting MSDN", but I'm not really sure what the problem even means. I also get this for the same line: CA1060 Move P/Invokes to NativeMethods class Because it is a P/Invoke method, 'IconUtil.SHGetFileInfo(string, uint, out IconUtil.SHFILEINFO, uint, uint)' should be defined in a class named NativeMethods, SafeNativeMethods, or UnsafeNativeMethods.