在编写跨平台位级代码时,字大小和字节顺序是否相互影响?

时间:2015-05-01 04:16:57

标签: c# endianness

我只是看this回答,它给出了以下示例代码,将int转换为字节数组:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
    Array.Reverse(intBytes);
byte[] result = intBytes;

我查了Endianness并发现字节的反转(或缺少字节)是一个单词的级别,它没有固定的长度。

上面的代码是否依赖于int是1个单词的大小?如果是这样,您将如何编写与平台无关的代码?

作为旁注,我很确定我记得,当天回来,查看调试器的内存视图,并且必须反转2组2个字节才能构造一个4字节的值...这是是什么让我思考这件事..

1 个答案:

答案 0 :(得分:3)

要正确处理字节序,您需要知道两件事:数据是大端还是小端,以及给定数据单位的大小。

这并不意味着您无法处理不同长度的数据。它 意味着您需要知道您正在处理的数据大小。

但无论如何这是真的。如果通过网络收到一系列字节(例如),则需要知道如何解释它们。如果你得到32个字节,那可能是文​​本,它可能是8个32位整数,也可能是4个64位整数,或者其他什么。

如果您期望32位整数,那么您需要一次处理32位(4字节)的字节序。如果您期望64位整数,则一次8个字节。这与为您的CPU架构,您的语言或托管运行时定义的“单词”无关。它与您的代码正在处理的协议有关。

即使在给定的协议中,不同的数据也可能是不同的大小。您可能混合使用shortintlong,并且需要适应这种情况。

这与以下原因完全相同: BitConverterBinaryReader使用或生成不同数量的字节,具体取决于您要检索的数据类型。只是不是消耗或生成不同数量的字节,而是反向(或者,如果平台字节序与协议匹配),则反转不同的字节数。

在您的示例中,如果您传递给BitConverter.GetBytes() long,那么编译器选择的重载将是采用long而不是int的方法。它会返回8个字节而不是4个字节。并且反转整个八个字节将是正确的事情。