编写跨平台位级代码时,字长和字节序会相互作用吗?
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 架构、您的语言或您的托管运行时定义的“词”是什么无关。它与您的代码正在处理的协议有关。
即使在给定的协议中,不同的数据也可能具有不同的大小。您可能会同时使用short
、int
和long
,您需要适应这种情况。
这与例如BitConverter
或 BinaryReader
使用或生成不同数量的字节,具体取决于您检索的数据类型。只是不是消耗或生成不同数量的字节,而是反转(或不,如果平台字节序与协议匹配)不同的字节数。
在您的示例中,如果您将long
传递给BitConverter.GetBytes()
,那么编译器选择的重载将是采用long
而不是int
的方法,它将返回八个字节而不是四个.并且反转整个八个字节是正确的做法。
【讨论】:
以上是关于编写跨平台位级代码时,字长和字节序会相互作用吗?的主要内容,如果未能解决你的问题,请参考以下文章