我如何解决这个“P / Invoke声明应该是可移植的”?

时间:2012-04-28 09:32:51

标签: c# pinvoke

此代码:

[DllImport("shell32", CharSet=CharSet.Unicode)]
private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);

导致以下代码分析问题:

  

CA1901 P / Invoke声明应该是可移植的

     

在代码中声明它是P / Invoke的返回类型   'IconUtil.SHGetFileInfo(字符串,uint,输出IconUtil.SHFILEINFO,uint,   uint)'在64位平台上将是4字节宽。这不正确,   因为此API的实际本机声明表明它应该是8   64位平台上的字节宽。请参阅MSDN Platform SDK   帮助确定应使用哪种数据类型的文档   而不是'int'。

我该怎么办?我试过“咨询MSDN”,但我不确定这个问题甚至意味着什么。


我也在同一条线上得到这个:

  

CA1060将P / Invokes移至NativeMethods类

     

因为它是P / Invoke方法,'IconUtil.SHGetFileInfo(string,uint,   out IconUtil.SHFILEINFO,uint,uint)'应该在类中定义   命名为NativeMethods,SafeNativeMethods或UnsafeNativeMethods。

2 个答案:

答案 0 :(得分:4)

警告引用的MSDN页面是本机函数SHGetFileInfo的文档。它的签名为:

DWORD_PTR SHGetFileInfo(
  __in     LPCTSTR pszPath,
  DWORD dwFileAttributes,
  __inout  SHFILEINFO *psfi,
  UINT cbFileInfo,
  UINT uFlags
);

所以第一个警告是指DWORD_PTR是指针大小无符号整数的事实。这意味着您应该使用UIntPtr

接下来跳出来的是SHFILEINFO结构被表示为__inout。这意味着您需要通过ref传递它。

所以p / invoke声明应该是:

[DllImport("shell32", CharSet=CharSet.Unicode)]
private static extern UIntPtr SHGetFileInfo(
    string pszPath, 
    uint dwFileAttributes, 
    ref SHFILEINFO psfi, 
    uint cbFileInfo, 
    uint flags
);

最终警告很容易解决。只需将p / invoke声明放在名为NativeMethods的类中。

答案 1 :(得分:0)

我通过将int的返回类型更改为IntPtr来解决了第一个问题。