2012-04-28 7 views
3

このコード:この「P/Invoke宣言は移植可能でなければならない」をどのように解決すればよいですか?

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

には、次のコード分析の問題が発生します。それはあなたのコード、戻り値の型で宣言されたよう

CA1901 P /呼び出し宣言は

移植する必要がありますP/Invoke 'IconUtil.SHGetFileInfo(string、uint、out IconUtil.SHFILEINFO、uint、 uint)'は、64ビットプラットフォームで4バイト幅になります。これは正しくありません。 は、このAPIの実際のネイティブ宣言として、64ビットプラットフォームでは8 バイトの幅であることを示しています。 「int」の代わりに を使用する必要があるデータ型を判断するためのヘルプは、MSDN Platform SDK のドキュメントを参照してください。

私は何をすべきですか?私は "consulting MSDN"を試みましたが、問題が何を意味するのかは分かりません。


私はまた、同じ行のためにこれを取得する:それはP/Invokeメソッドであるため

CA1060の移動Pは/(IconUtil.SHGetFileInfo」、NativeMethodsクラスに

を呼び出しますstring、uint、 、out IconUtil.SHFILEINFO、uint、uint) 'は、NativeMethods、SafeNativeMethods、またはUnsafeNativeMethodsという名前のクラス に定義する必要があります。

+3

'SHGetFileInfo'を' int'を返すと宣言しました。 'SHGetFileInfo'は' int'を返しますか? MSDNによると、それはしません。 x86では十分です。 x64では、そうではありません。それが最初のメッセージについてです。 – hvd

+0

疑問がある場合は、Pinvoke.Netをチェックしてください。通常、署名の権利があります。[SHGetFileInfo](http://www.pinvoke.net/default.aspx/shell32.shgetfileinfo)。もちろん、彼らが署名を間違えた場合、それはまた貢献することは良いですが、私は彼らがこの場合正しいと思います。 –

+0

[CA1060](http://msdn.microsoft.com/en-us/library/ms182161.aspx)はかなり明確です。メソッド宣言を 'IconUtil'という名前のクラスに配置しましたが、 'NativeMethods'、' SafeNativeMethods'、または 'UnsafeNativeMethods'という名前のクラスです。 3つのうちどれを使用すべきかをMSDNで確認してください。 – dtb

答えて

4

警告が参照するMSDNページは、ネイティブ関数SHGetFileInfoのドキュメントです。したがって、最初の警告がDWORD_PTRポインタサイズの符号なし整数であるという事実に言及さ

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

:それはのように署名を与えます。つまり、UIntPtrを使用する必要があります。

次は、SHFILEINFO構造体が__inoutと表示されています。つまり、refで渡す必要があります。

だから、P /呼び出し宣言は次のようになります。

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

最終警告を解決するのは簡単です。単純にp/invoke宣言をNativeMethodsというクラスの中に置きます。

0

私はIntPtrintの戻り値の型を変更することで、最初の問題を解決しました。

関連する問題