通常,c++ dll库字符编码方式都为utf-8,c#调用dll时,若遇到中文字符的接收与传递,会出现中文字符显示乱码与无法传递。
按照对应关系,若dll中参数为char[],例如char[64] name;则对于的c#字符定义为:
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string name;
若name为中文,
由于.NET平台多采用Unicode字符集,可能为gb2312,utf-16等;若此时对接收到的Name,做utf-8到Unicode的转换,仍不能得到正确结果;同样,对name进行Unicode到utf-8的转换,也不能正确传递数据。
原因在于从dll获取到的char已经隐式转换成为了string,由于utf-8与Unicode汉字编码字节数的不一致,导致隐式转换出错,之后再进行转换便不能得到正确结果。
解决方法:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] name;
采用byte[]接收或封装接收/传递的字符,再进行编码的转换。
以下为编码转换示例:
public static string GetDefaultString(byte[] utf8String)
{
utf8String = Encoding.Convert(Encoding.GetEncoding("UTF-8"), Encoding.Unicode, utf8String);
string strUnicode = Encoding.Unicode.GetString(utf8String);
strUnicode = strUnicode.Substring(0, strUnicode.IndexOf('\0'));
return strUnicode;
}
public static void GetUTF8Buffer(string inputString, int bufferLen, out byte[] utf8Buffer)
{
utf8Buffer = new byte[bufferLen];
byte[] tempBuffer = System.Text.Encoding.UTF8.GetBytes(inputString);
for (int i = 0; i < tempBuffer.Length; ++i)
{
utf8Buffer[i] = tempBuffer[i];
}
}