我不习惯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
微软可移植性
正如代码中所声明的那样,P / Invoke的返回类型
在64位平台上将为4字节宽。
这是不正确的,因为实际的本机声明
此API表示在64位平台上,该宽度应为8字节。
请查阅MSDN Platform SDK文档以帮助确定
应该使用哪种数据类型而不是'long'。

和(由于键盘布局名称只是数字,因此我认为这无关紧要):

CA2101
微软全球化
为了降低安全风险,可通过将DllImport.CharSet设置为CharSet.Unicode或将参数显式编组为UnmanagedType.LPWStr来将参数'pwszKLID'编组为Unicode。如果您需要将该字符串编组为ANSI或与系统相关的字符串,请显式指定MarshalAs,然后设置BestFitMapping = false;为了提高安全性,还设置ThrowOnUnmappableChar = true。

我尝试对第一个警告使用IntPtr,但这不能解决问题。有人可以帮我指出这些声明的正确格式吗?
谢谢!

最佳答案

您可以尝试使用以下声明:

[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。

09-25 17:47