什么是.NET中的MultibyteToWideChar和WideCharToMultiByte函数的替代方案?

时间:2016-11-10 12:20:32

标签: .net unicode encoding

我正在尝试将代码从VC ++迁移到.net。 VC ++代码使用WinAPI提供的MultibyteToWideChar和WideCharToMultiByte函数。我尝试在.NET中使用System.Text.Encoding类,但它不适用于所有编码。有没有其他方法可以进行此转换?下面的代码片段有什么问题?

这是我的C#代码:

public static string MultiByteToWideChar(string input, int codepage)
    {
        Encoding e1 = Encoding.GetEncoding(codepage);
        Encoding e2 = Encoding.Unicode;

        //byte[] source = e1.GetBytes(input);

        byte[] source = MBCSToByte(input);

        byte[] target = Encoding.Convert(e1, e2, source);

        return e2.GetString(target);
    }
public static string WideCharToMultiByte(string input, int codepage)
    {
        Encoding e1 = Encoding.Unicode;
        Encoding e2 = Encoding.GetEncoding(codepage);

        byte[] source = e1.GetBytes(input);

        byte[] target = Encoding.Convert(e1, e2, source);

        return Encoding.GetEncoding(codepage).GetString(target);

    }
private static byte[] MBCSToByte(string s)
    {
        byte[] b = new byte[s.Length];
        int i = 0;
        foreach (char c in s)
            b[i++] = (byte)c;
        return b;
    }

MultiByteToWideChar仅适用于代码页1255而不适用于866

WideCharToMultiByte不适用于代码页1251。

2 个答案:

答案 0 :(得分:1)

string是一个字符串,而不是字节流。当您将二进制数据包装在string中时,您已经丢失了。

如果您希望在编码之间进行适当的转换,请务必使用byte[]string已经赋予这些字节含义。 .NET的string与C char*不同。保留string的{​​{1}},并使用string进行持久性,网络等。

答案 1 :(得分:1)

MultiByteToWideChar()将编码的字节(非字符!)转换为Unicode字符。

WideCharToMultiByte()将Unicode字符转换为编码字节(非字符!)。

在.NET中,string类型始终是Unicode字符序列(采用UTF-16字节编码)。因此,使用string来保存编码的字节是完全错误的。

MultiByteToWideChar()函数中,您假设输入string包含Unicode字符,这些字符是代码页编码的8位字节的16位表示形式。您正在将Unicode字符按原样转换为byte[]数组,然后将该假设代码页编码的数组转换为UTF-16 byte[]数组,然后转换那是一个UTF-16 string。如果且仅当初始假设为真时,这将正常工作。通常情况并非如此,除非您的输入在开始时已损坏。

WideCharToMultiByte()函数中,您将输入string转换为UTF-16 byte[]数组,然后将该数组转换为代码页编码的byte[]数组。到目前为止一切顺利(尽管您可以使用Encoding.GetBytes()直接从UTF-16 string转到代码页编码byte[]而根本不使用Encoding.Convert()。但是,您使用相同的代码页将代码页编码的byte[]数组转换回UTF-16 string,从而取消了您所做的一切。输出string与输入string的值相同(前提是指定的代码页支持输入string中的所有Unicode字符,否则您将在第一个代码页中丢失数据转化率)。

话虽如此,正确的代码看起来应该更像这样:

public static string MultiByteToWideChar(byte[] input, int codepage)
    {
        return Encoding.GetEncoding(codepage).GetString(input);
    }
public static byte[] WideCharToMultiByte(string input, int codepage)
    {
        return Encoding.GetEncoding(codepage).GetBytes(input);
    }

请勿使用string来保存已编码的字节,而是使用实际的byte[]数组。