此问题已在此处有答案:
Marshalling a big-endian byte collection into a struct in order to pull out values(8个回答)
5年前关闭。
我有这个struct
:
[StructLayout(LayoutKind.Explicit)]
private struct Test
{
[FieldOffset(0)]
public readonly short Foo;
[FieldOffset(2)]
public readonly short Bar;
[FieldOffset(4)]
public readonly short Baz;
}
和以下字节数组:
var bytes = new byte[]
{
0x00, 0x01,
0x00, 0x05,
0xFF, 0xFB
};
我用下面的helper函数将字节数组转换为结构:
private static T ByteArrayToStructure<T>(byte[] bytes)
where T : struct
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
return (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
}
finally
{
handle.Free();
}
}
所以我使用它如下:
var test = ByteArrayToStructure<Test>(bytes);
Assert.AreEqual(1, test.Foo);
Assert.AreEqual(5, test.Bar);
Assert.AreEqual(-5, test.Baz);
现在看看Assert,我们可以清楚地看到我所期望的,如果结果不是这样,这个问题就会在这里。
似乎有什么东西在翻转这2个字节,所以对于第一个字节,它是0x0100
而不是0x0001
,对于第二个字节,它是0x0500
而不是0x0005
,对于最后一个字节,它是0xFBFF
而不是0xFFFB
。
是否有方法禁用此行为?
1条答案
按热度按时间vc6uscn91#
如果你想改变数据的字节序,这是不够的:
从那时起,您还将获得结构值的逆序:
只有当您知道结构中每个字段的大小时,才可以反转数组的字节顺序,以便您可以有选择地反转数组中各自的字节块。或者,你应该在结构的每个字段从数组中封送后对其执行字节交换,如下所示:
但我认为你的代码的逻辑是有缺陷的,如果你需要这样做。
我发现了许多替代的解决方案,就像@Sam Axe在他的推荐中发布的那样,或者this one。但我还是觉得这不是个好的练习