编写跨平台位级代码时,字长和字节序会相互作用吗?

Posted

技术标签:

【中文标题】编写跨平台位级代码时,字长和字节序会相互作用吗?【英文标题】:Do word size and endianness interplay when writing cross platform bit level code? 【发布时间】:2015-05-01 04:16:56 【问题描述】:

我只是在查看this 的答案,它提供了以下示例代码,用于将 int 转换为字节数组:

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

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

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

作为旁注,我很确定我记得,在过去,查看调试器的内存视图并且必须反转 2 组 2 字节以构造 4 字节值...这是是什么让我想到了这件事..

【问题讨论】:

在C#中,int is always Int32,所以没有问题。 @Blorgbeard,但是 Int32 是否可以存在于字大小为 2 字节的架构上? @AaronAnodide 除非 CPU 是middle-endian,否则不会改变字长 @xanatos,那么您是说在 32 位 CPU(即 4 字节字长)上,64 位整数将作为连续字节存在吗?换句话说,字节序不仅会影响单词中的字节顺序,还会影响值跨越多个单词的情况下的单词顺序……如果是这种情况,我想我可能会更好地理解…… "但是 Int32 是否可以存在于字大小为 2 字节的体系结构中" -- 是的,就像 Int64 可以并且确实存在一样,即使您正在运行您的x86(32 位)平台上的 .NET 程序。平台架构与可用的数据格式无关;最多,它会影响平台可以最有效地处理哪些数据格式。 【参考方案1】:

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

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

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

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

即使在给定的协议中,不同的数据也可能具有不同的大小。您可能会同时使用shortintlong,您需要适应这种情况。

这与例如BitConverterBinaryReader 使用或生成不同数量的字节,具体取决于您检索的数据类型。只是不是消耗或生成不同数量的字节,而是反转(或不,如果平台字节序与协议匹配)不同的字节数。

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

【讨论】:

以上是关于编写跨平台位级代码时,字长和字节序会相互作用吗?的主要内容,如果未能解决你的问题,请参考以下文章

辨析:机器字长存储字长指令字长和操作系统位数

字长和数据类型

字长和数据类型

C语言数据类型中int与short的区别

RAM的字长、字宽、字数、位宽等表述

机器字长,存储字长,字节