我不习惯P / Invoke,但我应该声明一些WinAPI函数来获取或设置键盘布局。我声明了这样的函数:
[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应用程序中)时,我收到警告:
CA1901 Microsoft.Portability 正如在代码中声明的那样,P / Invoke的返回类型 在64位平台上将是4字节宽。 这是不正确的,因为实际的原生声明 此API表明它应该在64位平台上为8字节宽。 有关帮助确定,请参阅MSDN Platform SDK文档 应该使用什么数据类型而不是'long'。
和(我认为这不太关心,因为键盘布局名称只是数字):
CA2101 Microsoft.Globalization 要降低安全风险,请将参数'pwszKLID'编组为Unicode,方法是将DllImport.CharSet设置为CharSet.Unicode,或者将参数显式封送为UnmanagedType.LPWStr。如果需要将此字符串封送为ANSI或系统相关,请明确指定MarshalAs,并设置BestFitMapping = false;为了增加安全性,还要设置ThrowOnUnmappableChar = true。
我尝试使用IntPtr进行第一次警告,但这并没有解决问题。有人可以指点我这些声明的正确形式吗? 谢谢!
答案 0 :(得分: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。将两种方法的返回值调整为正确的返回类型,并为MarshalAs
上的返回添加GetKeyboardLayoutName
将清除CA1901。
答案 1 :(得分:0)
LoadKeyboardLayout返回HKL,实际上是void *。
typedef PVOID HANDLE; typedef HANDLE HKL;
GetKeyboardLayoutName返回BOOL,实际上是32位int。所以,你需要定义 LoadKeyboardLayout返回类型为IntPtr,GetKeyboardLayoutName返回类型为int。