编写跨平台位级代码时,字长和字节顺序会相互作用吗?
Do word size and endianness interplay when writing cross platform bit level code?
我只是在查看 this 答案,其中提供了以下示例代码,可将 int 转换为字节数组:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
byte[] result = intBytes;
我查了下Endianness,发现字节的反转(或缺失)是在字的层面上,没有固定的长度。
上面的代码是否依赖于int是1个字的大小?如果是这样,您将如何编写与平台无关的代码?
作为旁注,我相当确定我记得,回到当天,查看调试器的内存视图并且必须反转 2 组 2 字节才能构造 4 字节值...这就是让我思考这个问题的原因..
要正确处理字节顺序,您需要知道两件事:数据是大端还是小端,以及给定数据单元的大小。
这并不意味着您不能处理不同长度的数据。 确实意味着您需要知道您正在处理的数据大小。
但这无论如何都是真的。如果您通过网络接收到一系列字节(例如),您需要知道如何解释它们。如果你得到 32 个字节,它可能是文本,它可能是八个 32 位整数,它可能是四个 64 位整数,或其他任何东西。
如果您需要一个 32 位整数,那么您需要一次处理 32 位(4 字节)字节顺序。如果您需要一个 64 位整数,则一次 8 个字节。这与 "word" 为您的 CPU 体系结构、您的语言或您管理的 运行 时间定义的内容无关。它与您的代码正在处理的协议有关。
即使在给定的协议中,不同的数据片段也可能有不同的大小。您可能混合使用 short
、int
和 long
,您需要适应这种情况。
这与例如BitConverter
或 BinaryReader
消耗或生成不同数量的字节,具体取决于您检索的数据类型。只是不是消耗或生成不同数量的字节,而是反转(或不反转,如果平台字节顺序与协议匹配)不同的字节数。
在您的示例中,如果您向 BitConverter.GetBytes()
传递了一个 long
,那么编译器选择的重载将是采用 long
而不是 int
的方法] 并且它将 return 八个字节而不是四个。并且反转整个八个字节将是正确的做法。
我只是在查看 this 答案,其中提供了以下示例代码,可将 int 转换为字节数组:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
byte[] result = intBytes;
我查了下Endianness,发现字节的反转(或缺失)是在字的层面上,没有固定的长度。
上面的代码是否依赖于int是1个字的大小?如果是这样,您将如何编写与平台无关的代码?
作为旁注,我相当确定我记得,回到当天,查看调试器的内存视图并且必须反转 2 组 2 字节才能构造 4 字节值...这就是让我思考这个问题的原因..
要正确处理字节顺序,您需要知道两件事:数据是大端还是小端,以及给定数据单元的大小。
这并不意味着您不能处理不同长度的数据。 确实意味着您需要知道您正在处理的数据大小。
但这无论如何都是真的。如果您通过网络接收到一系列字节(例如),您需要知道如何解释它们。如果你得到 32 个字节,它可能是文本,它可能是八个 32 位整数,它可能是四个 64 位整数,或其他任何东西。
如果您需要一个 32 位整数,那么您需要一次处理 32 位(4 字节)字节顺序。如果您需要一个 64 位整数,则一次 8 个字节。这与 "word" 为您的 CPU 体系结构、您的语言或您管理的 运行 时间定义的内容无关。它与您的代码正在处理的协议有关。
即使在给定的协议中,不同的数据片段也可能有不同的大小。您可能混合使用 short
、int
和 long
,您需要适应这种情况。
这与例如BitConverter
或 BinaryReader
消耗或生成不同数量的字节,具体取决于您检索的数据类型。只是不是消耗或生成不同数量的字节,而是反转(或不反转,如果平台字节顺序与协议匹配)不同的字节数。
在您的示例中,如果您向 BitConverter.GetBytes()
传递了一个 long
,那么编译器选择的重载将是采用 long
而不是 int
的方法] 并且它将 return 八个字节而不是四个。并且反转整个八个字节将是正确的做法。