我一直在使用 Microsoft P/Invoke Interop Assistant 工具从本机 C/C++ 代码生成一些结构、委托等。
其中一个示例是函数指针(委托),它在托管代码中解析为以下名称:
EnumCalendarInfoProcA
EnumCalendarInfoProcW
EnumCalendarInfoProcExA
EnumCalendarInfoProcExW
谁能解释A和W以及ExA和ExW之间的区别?
我一直在使用 Microsoft P/Invoke Interop Assistant 工具从本机 C/C++ 代码生成一些结构、委托等。
其中一个示例是函数指针(委托),它在托管代码中解析为以下名称:
EnumCalendarInfoProcA
EnumCalendarInfoProcW
EnumCalendarInfoProcExA
EnumCalendarInfoProcExW
谁能解释A和W以及ExA和ExW之间的区别?
一些函数有多种格式。Ascii (MessageBoxA) 或宽字符/unicode (MessageBoxW)。当一个函数做同样的事情,但更多的时候,这个名字通常会得到一个后缀“Ex”,并且可能意味着扩展。
像下面的函数
消息框:http : //msdn.microsoft.com/en-us/library/windows/desktop/ms645505 (v=vs.85).aspx
MessageBoxEx: http: //msdn.microsoft.com/en-us/library/windows/desktop/ms645507 (v=vs.85).aspx
其中 MessageBoxEx 由参数 wLanguageId 扩展。
您必须小心使用 PInvoke 互操作助手。它生成的声明是完全自动生成且未经编辑的。因此,它往往会产生相当尴尬的结果,您至少需要与经过编辑的声明源进行比较,例如可从 pinvoke.net 网站和 MSDN 库获得的声明源。
存在 A 和 W 版本是因为该函数操作字符串。9x 分支中的旧版本 Windows 未启用 Unicode。他们使用 A 版本,带有 8 位编码字符的字符串。这与 Windows ME 迅速而当之无愧的消亡无关。您今天遇到的所有 Windows 版本都来自 NT 分支,并且它们在核心上启用了 Unicode。
pinvoke marshaller 已经知道如何根据 [DllImport] 属性中的 CharSet 属性在 A 和 W 版本之间进行正确选择。遗憾的是,默认仍然是 Ansi,大错误,您应该始终指定 CharSet.Auto 并使用不带 W 的名称。确切的名称对于 EnumCalendarInfoProc 实际上并不重要,因为它是回调原型,您将其声明为委托。您可以选择任何名称。
EnumCalendarInfoProc 和 EnumCalendarInfoProcEx 的区别在 MSDN 文章中有很好的解释,Ex 版本有一个额外的参数。你需要使用哪一个取决于你开始枚举时使用的 api 函数。选择 EnumCalendarInfo() 或 EnumCalendarInfoEx()。后一种是有道理的。请注意 ExEx 版本,可在 Vista 及更高版本上使用。文化的变化比微软创建 Exes 的能力更快;)
在委托和函数声明上应用 CharSet.Auto。