2011-07-05 10 views
2

私はP/Invokeに慣れていませんが、キーボードレイアウトを取得または設定するためのWinAPI関数をいくつか宣言する必要があります。 、C#P/Invoke forキーボードレイアウトとコンパイラの警告

CA1901それはあなたのコード内で宣言されたよう Microsoft.Portability :私は次のような機能を宣言:


[DllImport("user32.dll")] 
private static extern long LoadKeyboardLayout(
    string pwszKLID, // input locale identifier 
    uint Flags   // input locale identifier options 
    ); 

[DllImport("user32.dll")] 
private static extern long GetKeyboardLayoutName(
    StringBuilder pwszKLID //[out] string that receives the name of the locale identifier 
    ); 

しかし、私は(C#WPFアプリケーションで)これをコンパイルするとき、私は警告を取得しますP/Invoke の戻りタイプは、64ビットプラットフォームで4バイト幅になります。 このAPIの実際のネイティブ宣言である は、64ビットプラットフォームでは8バイト幅であることを示しているため、これは正しくありません。 「long」の代わりに使用するデータ型を決定するためのヘルプは、MSDN Platform SDKのドキュメントを参照してください。

と(私はこれはキーボードレイアウト名は単なる数字ですとそれほど懸念されると仮定):DLLIMPORTを設定することで、マーシャルパラメータはUnicodeとして「pwszKLID」、セキュリティ上のリスクを減らすために

CA2101 Microsoft.Globalization .CharSetをCharSet.Unicodeに設定するか、パラメータをUnmanagedType.LPWStrとして明示的にマーシャリングします。この文字列をANSIまたはシステム依存としてマーシャリングする必要がある場合は、MarshalAsを明示的に指定し、BestFitMapping = falseを設定します。さらにセキュリティを強化するには、ThrowOnUnmappableChar = trueに設定します。

最初の警告としてIntPtrを使用しようとしましたが、これで問題は解決しません。誰も私にこれらの宣言の正しい形式を指摘することによって助けてくれますか? ありがとう!

答えて

1

次の宣言を使用して試すことができます:

[DllImport("user32.dll", CharSet=CharSet.Unicode)] 
private static extern IntPtr LoadKeyboardLayout(
    string pwszKLID, // input locale identifier 
    uint Flags   // input locale identifier options 
    ); 

[DllImport("user32.dll", CharSet = CharSet.Unicode)] 
[return : MarshalAs(UnmanagedType.Bool)] 
private static extern bool GetKeyboardLayoutName(
    StringBuilder pwszKLID //[out] string that receives the name of the locale identifier 
    ); 

CharSet仕様はCA2101をクリアします。両方のメソッドの戻り値を正しい戻り値の型に調整し、GetKeyboardLayoutNameの戻り値にMarshalAsを追加すると、CA1901がクリアされます。

+0

C# 'bool'のデフォルトマーシャリングはWindowsの' BOOL'と同じです。したがって、MarshalAsは必要ありません。 –

+0

@David、私はもともとそれをそのまま残していましたが、Naftisが警告を引き起こしているようにCode Analysisをオンにして、警告が表示されました。したがって、マーシャルの追加。 –

0

LoadKeyboardLayoutは、実際にvoid *であるHKLを返します。

 
typedef PVOID HANDLE; 
typedef HANDLE HKL; 

GetKeyboardLayoutNameは、実際には32ビットのint型のBOOLを返します。したがって、 LoadKeyboardLayoutの戻り値の型をIntPtrとして、GetKeyboardLayoutNameの戻り値の型をintとして定義する必要があります。

+0

ありがとうございますこれは、第1警告のために働いた! 2番目は安全に無視することができると思います... – Naftis

関連する問題