【问题标题】:C# Converting from byte[] to struct. The byte order is wrongC# 从 byte[] 转换为 struct。字节顺序错误
【发布时间】:2010-08-16 10:27:16
【问题描述】:

在实现基于 UDP 的协议时,我试图使用结构来解析套接字数据。 我搜索了一下,我可以使用这两个函数在 byte[] 和 struct 之间进行转换:

 byte[] StructToBytes(object structObj)
    {
        int size = Marshal.SizeOf(structObj);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.StructureToPtr(structObj, buffer, false);
            byte[] bytes = new byte[size];
            Marshal.Copy(buffer, bytes, 0, size);
            return bytes;
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }

    }

    static object BytesToStruct(byte[] bytes, Type strcutType, int offset = 0)
    {
        int size = Marshal.SizeOf(strcutType);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.Copy(bytes, offset, buffer, size);
            return Marshal.PtrToStructure(buffer, strcutType);
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

然后我遇到了这个问题:

//I defined a simple struct with an ushort member
    [StructLayout(LayoutKind.Sequential, Pack = 2)]
    struct S
    {
        public ushort a;
    }

    //Then I define a byte[]
    byte[] bArr;
    bArr[0] = 0;
    bArr[1] = 1;

    //Convert to struct
    S s = (S)BytesToStruct(bArr, typeof(S));
    //Then s.a = 0x0100 not 0x0001

和 struct to byte[] 是一样的。 ushort 的 2 个字节被反转。 我该如何解决这个问题?

【问题讨论】:

    标签: c# struct marshalling byte


    【解决方案1】:

    如今,大多数处理器都使用 Little-Endian 字节排序(最低有效字节在前)。网络字节序是传统的 Big-Endian,所以通常需要镜像字节序。您可以使用System.BitConverter.IsLittleEndian检查系统的字节序

    弗兰克提到的 ntohs() 的 .Net 等价物位于(奇怪的是)System.Net.IPAddress.NetworkToHostOrder()

    您还可以编写自己的机制,使用位移和逻辑 OR 直接以正确的顺序读取字节。

    【讨论】:

      【解决方案2】:

      网络字节序和主机字节序是有区别的。

      通常,至少在 C 中,您在从套接字读取时使用 ntohl()、ntohs() 和朋友将网络字节顺序转换为您的主机顺序。

      【讨论】:

        【解决方案3】:

        问题与系统上short 的字节顺序有关。看看this question about endianness,它可能会提供一些指针(双关语无意)。

        另外,我建议将BytesToStruct 设为struct 的泛型:

        static S BytesToStruct<S>(byte[] bytes, int offset = 0)
        

        所以它可以被调用

        BytesToStruct<S>(bArr)
        

        而不是现在

        (S)BytesToStruct(bArr, typeof(S))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-21
          • 2013-04-14
          • 1970-01-01
          • 2011-12-23
          • 2013-06-30
          • 2017-12-12
          • 1970-01-01
          相关资源
          最近更新 更多