编组短裤翻转顺序c#

时间:2017-12-26 00:22:23

标签: c# .net marshalling

我有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
};

我将我的字节数组转换为具有以下辅助函数的结构:

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);

现在看看Asserts,我们可以清楚地看到我所期待的,如果结果不是这样的话,这个问题就会在这里。

似乎某些东西正在翻转2个字节,因此对于第一个字节,它是0x0100而不是0x0001,对于第二个字节,它出现为0x0500而不是0x0005 {1}},最后一个显示为0xFBFF而不是0xFFFB

有没有办法禁用此行为?

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您想更改数据的字节顺序,这还不够:

Array.Reverse(data);
Test t = ByteArrayToStructure<Test>(bytes);

从那时起,您还将获得结构值的相反顺序:

t.Foo will be -5
t.Bar will be 5
t.Baz will be 1

只有知道结构中每个字段的大小,才能反转数组的字节顺序,这样才能有选择地反转数组中各自的字节块。或者,您应该在从阵列封送后对结构的每个字段执行字节交换,如下所示:

Test t = ByteArrayToStructure<Test>(bytes);
t.Foo = SwapBytes(t.Foo);
t.Bar = SwapBytes(t.Bar);
t.Baz = SwapBytes(t.Baz);

private static short SwapBytes(short value)
{
    return (short)((value >> 8) | ((value & 0xFF) << 8));
}

但我认为如果你需要这样做,代码的逻辑是有缺陷的。

我找到了许多替代解决方案,比如@Sam Ax在他的推荐中发布的解决方案,或this one ......但我仍然认为这不是一个好习惯。