我注意到,从mme读取midi端口名时,这些名称是使用ansi代码页编码的多字节字符串,我的应用程序默认使用该代码页。从DirectMusic驱动程序接收这些名称时,这些名称是用OEM代码页编码的宽字符串。有关代码页上的快速刷新,请参见this article by Raymond Chen。
在我的德语系统中,这意味着当使用当前的代码页时,我从mme得到“audioger_t”,从directmusic得到“audioger_t”,后者是错误的。当我把这个姓氏改为oem编码时,这个问题就解决了。
那么我怎么知道用哪个代码页来解码这些名字呢?为什么来自directmusic的名称编码不同?它来自USB驱动程序吗?COM框架?直接音乐?我如何确定在读取MIDI端口名称时要使用哪个代码页?
信息:
我使用MultiByteToWideChar()
和WideCharToMultiByte()
函数来执行转换,使用CP_ACP
和CP_OEMCP
作为代码页的参数。
我使用midiInGetDeviceCaps()
从mme子系统获取midi端口信息…
…并使用MIDIINCAPS.szPname
(ANSI)代码页转换CP_ACP
。
我使用IID_IDirectMusic8::EnumPort()
从DirectMusic获取端口信息…
…并使用DMUS_PORTCAPS.wszDescription
代码页转换CP_OEMCP
。
最佳答案
我不知道directmusic框架为什么会使用一组代码页,而使用另一组代码页,但这里的解决方案可能是构建一个抽象层,然后为每个api制定特定的实现。这样,您的软件的更高级别就不需要关注这样的细节。
也就是说,端点名称肯定来自操作系统。USB MIDI设备只指定端点类型(即输入或输出,以及编号),但操作系统可以根据需要自由解释它们,这就是它们本地化的原因。
没有特定的api调用(据我所知)来确定框架将在哪个代码页中传递其字符串。然而,directmusic似乎确实使用了带有oem代码页的双宽字符作为通用约定,尽管我在任何msdn文档中都找不到明确的说明。在MSDN DirectMusic documentation about MIDI port capability structures中,描述类型显然被定义为wchar,Game Audio Programming一书似乎还表明该类型是api范围的约定。虽然假设oem是这些字符的默认编码是很危险的,但我找不到其他的东西(搜索“directmusic codepage”现在将此页面列为热门)。
编辑:查看这个stackoverflow question on determining the current OS codepage。directmusic api可能以这种方式设置代码页。