C# 编组P/Invoke

C# 编组P/Invoke,c#,vb.net,pinvoke,C#,Vb.net,Pinvoke,VS代码分析器抛出以下警告: CA2101指定p/Invoke字符串参数的封送处理以减少 安全风险,通过设置将参数“buffer”封送为Unicode DllImport.CharSet转换为CharSet.Unicode,或通过显式封送 参数为UnmanagedType.LPWStr。如果需要封送此字符串 作为ANSI或系统相关,显式指定MarshalAs,并设置 BestFitMapping=false;为了增加安全性,还设置 ThrowOnUnmappableChar=true。Reg2B

VS代码分析器抛出以下警告:

CA2101指定p/Invoke字符串参数的封送处理以减少 安全风险,通过设置将参数“buffer”封送为Unicode DllImport.CharSet转换为CharSet.Unicode,或通过显式封送 参数为UnmanagedType.LPWStr。如果需要封送此字符串 作为ANSI或系统相关,显式指定MarshalAs,并设置 BestFitMapping=false;为了增加安全性,还设置 ThrowOnUnmappableChar=true。Reg2Bat CenteredMSGBox.vb 20

在这里:

_
共享函数GetClassName(hWnd作为IntPtr,缓冲区作为System.Text.StringBuilder,buflen作为Integer)作为Integer
端函数

我需要使用ANSI编码,但我不明白我需要做什么,所以我需要如何处理它?

这里是来自的声明

如果您(出于任何原因)想要导入ASCII版本,那么

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern int GetClassNameA(
    IntPtr hWnd, 
    StringBuilder lpClassName,
    int nMaxCount
);
另一种方法是为单个参数指定编组行为,如中所示

[DllImport("user32.dll", SetLastError = true)]
static extern int GetClassNameA(
    IntPtr hWnd, 
    [MarshalAs(UnmanagedType.LPStr)] StringBuilder lpClassName,
    int nMaxCount
);

为什么需要使用ANSI版本?@David Heffernan我很困惑,我根本不需要ANSI。你能解释一下SetLastError属性的含义吗?@Recipe文档解释了这一点
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern int GetClassNameA(
    IntPtr hWnd, 
    StringBuilder lpClassName,
    int nMaxCount
);
[DllImport("user32.dll", SetLastError = true)]
static extern int GetClassNameA(
    IntPtr hWnd, 
    [MarshalAs(UnmanagedType.LPStr)] StringBuilder lpClassName,
    int nMaxCount
);