Unity3D中的Encoding.UTF32.GetBytes返回额外的ZERO

时间:2016-12-10 02:54:28

标签: c# unity3d encoding

var combined = arr.reduce(function(a, item, idx) {
    var found = false;
    for (var i = 0; i < a.length; i++) {
        if (a[i].id == item.id) {
            a[i].classes = a[i].classes.concat(item.classes);
            found = true;
            break;
        }
    }

    if (!found) {
        a.push(item);
    }

    return a;
}, []);

在Visual Studio中运行此代码,输出

char[] chars = new char[]
{
    (char)0xd83d, (char)0xde04,
};
byte[] bytes = Encoding.UTF32.GetBytes(chars);
Console.WriteLine("bytes.Length = " + bytes.Length);

foreach (var b in bytes)
{
    Console.WriteLine(b.ToString("x2"));
}

但在Unity中,输出是

bytes.Length = 4
04
f6
01
00

为什么?

B.T.W。 0xd83d,0xde04是一个表情符号。它应该等于Unicode U + 1F604,所以我认为bytes.Length = 8 04 f6 01 00 00 00 00 00 应该是4(一个UInt32)。

----------------编辑------------------------------ ---

在Visual Studio中,bytes.Length返回原始字符

但在Unity中,Encoding.UTF32.GetChars(the 4 bytes)会返回不同的字符

所以我认为这是一个错误

2 个答案:

答案 0 :(得分:1)

右键单击.ToString("x2"),然后“转到定义”。

你会在常规的VS项目中看到:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\mscorlib.dll

但是在Unity项目中你会得到:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Unity Subset v3.5\mscorlib.dll

我怀疑框架版本(3.5 vs 4.5)是原因。我认为“统一子集”的实现方式不同。

现在,如果你问为什么统一子集的dll以它的方式实现它 - 我不知道。

答案 1 :(得分:1)

看起来编码可能会在那里偷一个空终结器。分离32位值:

0x04 0xf6 0x01 0x00  // 0x0001f604
0x00 0x00 0x00 0x00  // 0x00000000 (NUL)

如果顶行看起来令人困惑,那是因为字节顺序是小端的。

因此,Encoding.UTF32.GetBytes首先正确输出UTF-16代理对作为UTF-32字符,并附加一个空字符。

不幸的是,由于我没有兼容的机器,我现在无法对此进行测试,但请尝试以下方法:

  1. 将代理对(char)0xd83d, (char)0xde04两次添加到char数组中并运行相同的程序 - 如果bytes的长度为12且最后四个字节全为零则为答案是合理的,如果长度为16(并且字节只是两个相同的八字节序列),似乎编译器出于某种原因使用64位UInt来表示UTF-32字符。

  2. 请考虑关注Microsoft's suggestion

      

    考虑使用Encoder.Convert方法而不是GetByteCount。转换方法转换尽可能多的数据,如果输出缓冲区太小,则会抛出异常。对于流的连续编码,此方法通常是最佳选择。