2016-11-10 67 views
-1

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

这里是我的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

+1

什么是不工作,你为什么要使用C++函数名的东西** **完全不同? 'Encoding'没有问题。如果您使用正确的代码页,它可以将任何内容从一种编码转换为另一种编码。结束工作在其他功能上仅仅是保证你会得到转换错误 –

+0

总结 - *什么*你要转换? 1255到Unicode? 1255至866?完全相同的代码可以在任何情况下工作 –

+1

.NET字符串是Unicode * always *。你是否试图修复一个损坏的字符串?没有多字节或宽字符串。如果你想将一个字符串转换为一个1255字节数组只需使用'Encoging.GetEncoding(1255).GetBytes(someString);'。如果你想从1255阵列得到一个Unicode字符串,用'Encoging.GetEncoding(1255).GetString(someString);我正在写' –

回答

1

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

WideCharToMultiByte() Unicode字符转换到编码的字节(不是字符!)。

在.NET中,string类型总是的Unicode字符序列(在UTF-16字节编码)。所以使用string来保存编码的字节是错误的。

在你MultiByteToWideChar()功能,你假设,输入string包含的代码页的编码8位字节的16位表示Unicode字符。您将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[]阵列代替。

+0

代码是CLR存储过程的一部分。我从SQL存储过程传入​​此CLR存储过程的输入。传入的输入类型是varchar和nvarchar。 SQL存储过程应该做什么来以字节数组而不是字符串形式传入输入。以下是正在调用多字节到unicode函数的sql代码,并将unicode字节转换为out参数。 '声明@input VARCHAR(2000) DECLARE @output VARBINARY(4000) DECLARE @outputup为nvarchar(2000) 组@input = 'XXXXXXXXXXXXXXXXXXXXŽƒŽŠ€€ - ...‰'',€Z' EXEC cp2u @input,866 ,@output OUTPUT ' – Mahesh

+0

和预期输出,这是“ОГОКАЗНАЧЕЙСТВАПО” – Mahesh

+0

,你为什么和字符编码处理手动呢?根据所涉及字段的声明字符集和归类,让SQL数据库为您处理该数据库。 –

1

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

如果你想编码之间的正确转换,确保使用byte[]string已经给这些字节赋予了含义。 .NET的string与C的char*不一样。保留stringstring s,并使用byte[]进行持久性,网络连接等。

相关问题