.net 编组短裤翻转顺序c# [重复]

guykilcj  于 2023-05-01  发布在  .NET
关注(0)|答案(1)|浏览(61)

此问题已在此处有答案

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
是否有方法禁用此行为?

vc6uscn9

vc6uscn91#

如果你想改变数据的字节序,这是不够的:

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 Axe在他的推荐中发布的那样,或者this one。但我还是觉得这不是个好的练习

相关问题