c# - 如何防止将 Windows-1252 参数转换为 Unicode 字符串?

标签 c# com

我已经编写了我的第一个 COM 类。我的单元测试工作正常,但我第一次使用 COM 对象时遇到了障碍。

COM 类提供接受字符串、操作它并返回字符串的方法。 COM 对象的使用者是 dBASE PLUS 程序。

当输入字符串包含常见的键盘字符(ASCII 127 或更低)时,COM 方法可以正常工作。但是,如果字符串包含超出 ASCII 范围的字符,其中一些字符会从 Windows-1252 重新映射到 C# 的 Unicode。此表显示发生的映射:http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT

例如,如果 dBASE 程序调用 COM 对象:

oMyComObject.MyMethod("It will cost123") 其中 € 为十六进制 80,

C# 方法将其作为 Unicode 接收:

public string MyMethod(string source)
{
    // source is Unicode and now the Euro symbol is hex 20AC
    ...
}

我想避免这种重新映射,因为我想要字符串的原始十六进制内容。

我尝试将以下内容添加到 MyMethod 以将字符串转换回 Windows-1252,但欧元符号丢失了,因为它变成了问号:

        byte[] UnicodeBytes = Encoding.Unicode.GetBytes(source.ToString());
        byte[] Win1252Bytes = Encoding.Convert(Encoding.Unicode, Encoding.GetEncoding(1252), UnicodeBytes);
        string Win1252 = Encoding.GetEncoding(1252).GetString(Win1252Bytes);

有没有办法阻止将“源”参数转换为 Unicode?或者,有没有办法将它 100% 从 Unicode 转换回 Windows-1252?

最佳答案

是的,我正在回答我自己的问题。 “Jigsore”的回答让我走上了正确的道路,但我想更清楚地解释一下,以防其他人犯同样的错误。

我最终发现我误诊了问题。 dBASE 可以很好地传递字符串,而 C# 可以很好地接收它。这就是我检查错误字符串内容的方式。

这个统包建立在 Jigsore 的回答之上:

void Main()
{
    string unicodeText = "\u20AC\u0160\u0152\u0161";

    byte[] unicodeBytes = Encoding.Unicode.GetBytes(unicodeText);
    byte[] win1252bytes = Encoding.Convert(Encoding.Unicode, Encoding.GetEncoding(1252), unicodeBytes);
    for (int i = 0; i < win1252bytes.Length; i++)
        Console.Write("0x{0:X2} ", win1252bytes[i]); // output: 0x80 0x8A 0x8C 0x9A

    // win1252String represents the string passed from dBASE to C#
    string win1252String = Encoding.GetEncoding(1252).GetString(win1252bytes);

    Console.WriteLine("\r\nWin1252 string is " + win1252String); // output: Win1252 string is €ŠŒš
    Console.WriteLine("looking at the code of the first character the wrong way: " + (int)win1252String[0]);
    // output: looking at the code of the first character the wrong way: 8364

    byte[] bytes = Encoding.GetEncoding(1252).GetBytes(win1252String[0].ToString());

    Console.WriteLine("looking at the code of the first character the right way: " + bytes[0]);
    // output: looking at the code of the first character the right way: 128

    // Warning: If your input contains character codes which are large in value than what a byte
    // can hold (ex: multi-byte Chinese characters), then you will need to look at more than just bytes[0].
}

第一种方法错误的原因是强制转换 (int)win1252String[0](或者使用 (char)j 将整数 j 转换为字符的逆过程) >) 涉及 C# 使用的 Unicode 字符集的隐式转换。

我认为此问题已解决,并感谢每个花时间发表评论或回答问题的人。不胜感激!

关于c# - 如何防止将 Windows-1252 参数转换为 Unicode 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13021834/

相关文章:

.net - 从 64 位 .NET 程序连接到 32 位 Access 数据库

c# - 从 C# 访问 COM vtable

c# - Tuple<...> 在另一种类型中的 Json.NET 反序列化不起作用?

c# - 替换 DataColumn 中的值

c# - XPath 不适用于 SelectSingleNode

c# - C++ 程序在调用 C# 接口(interface)时接收 HOST_E_CLRNOTAVAILABLE

c# - 如何在 C# 中从 IFileDialogCustomize GetEditBoxText() 获取字符串

c# - 方法 'Where' 不能遵循方法 'Select' 或不受支持

c# 如何按值列对排序列表进行排序

c# - 如何在通过 COM 交互时 "lock"excel