我正在为不支持Unicode字符串但支持多字节ANSI字符串的库的PInvoke包装器。在调查图书馆的FxCop报告时,我注意到正在使用的字符串编组有一些有趣的副作用。 PInvoke方法使用“最佳拟合”映射来创建单字节ANSI字符串。为了说明,这是一个方法,看起来像:如何PInvoke多字节ANSI字符串?
[DllImport("thedll.dll", CharSet=CharSet.Ansi)]
public static extern int CreateNewResource(string resourceName);
调用与包含非ASCII字符是Windows找到“关闭”字符的字符串这个函数的结果,通常这看起来像它结束存在 ”???”。如果我们假装'a'是非ASCII字符,那么传递“cat”作为参数将创建一个名为“c?t”的资源。
如果我遵循的FxCop规则的指引,我结束了这样的事情:
[DllImport("thedll.dll", CharSet=CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern int CreateNewResource([MarshalAs(UnmanagedType.LPStr)] string resourceName);
这引入了行为的改变;现在当一个字符不能被映射时抛出一个异常。这关系到我,因为这是一个突破性的改变,所以我想尝试将字符串编组为多字节ANSI,但是我看不到这样做的方法。 UnmanagedType.LPStr
被指定为单字节ANSI字符串LPTStr will be Unicode or ANSI depending on the system, and LPWStr is not what the library expects.
How would I tell PInvoke to marshal the string as a multibyte string? I see there's a
为我在非托管内存中创建的字符串?看起来,这仍然存在许多当前实现的问题(它仍然可能需要删除或替换字符),所以我不确定这是否有所改进。我错过了另一种编组方法吗?WideCharToMultiByte()
API函数,我是否可以更改签名以期望IntPtr
我看你是对的;我在当前代码页之外进行了字符测试,并且无法想象任何实际上可以在我的代码页中工作的多字节字符。我在摸索着试着找到一个代码页/字符组合,我可以把它放到函数中来获得一些信心,但我认为你是对的。 – OwenP 2009-04-30 19:13:30
我想出了如何测试它:我使用了一个用于日文本地化的XP的映像,并设置了一些名称由大量日文字符组成的资源。这在日本机器上效果很好,但是在英文机器上失败了。 我会*喜欢*的行为就好像我使用Unicode一样,但从您的解释和实验中我发现这是不可能的,而且我已经越来越接近它了。我只需等待库的维护者实现Unicode支持。 – OwenP 2009-04-30 22:10:47