简体   繁体   English

C#从byte []转换为struct。 字节顺序错误

[英]C# Converting from byte[] to struct. The byte order is wrong

I was trying to use a struct to parse socket data when implement a UDP based protocol. 在实现基于UDP的协议时,我试图使用结构来解析套接字数据。 And I searched and I can use these 2 functions to convert between byte[] and struct: 我搜索了,我可以使用这两个函数在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);
        }
    }

Then I had this problem: 然后我遇到了这个问题:

//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

And struct to byte[] is just the same. 而struct到byte []也是一样的。 The 2 bytes of ushort are reversed. ushort的2个字节是相反的。 How do I solve this problem? 我该如何解决这个问题?

Most processors these days use Little-Endian byte ordering (Least significant byte comes first). 如今大多数处理器都使用Little-Endian字节排序(最低有效字节排在第一位)。 Network byte ordering is traditional Big-Endian, so you usually need to mirror the byte order. 网络字节排序是传统的Big-Endian,因此您通常需要镜像字节顺序。 You can check the endianness of the system with System.BitConverter.IsLittleEndian 您可以使用System.BitConverter.IsLittleEndian检查系统的字节顺序

The .Net equivalent of ntohs() Frank mentioned is located (oddly) at System.Net.IPAddress.NetworkToHostOrder() 提到的ntohs()的.Net等价物(奇怪地)位于System.Net.IPAddress.NetworkToHostOrder()

You could also write your own mechanism to read the bytes in the correct order directly, using bit shifting and logical OR. 您还可以编写自己的机制,使用位移和逻辑OR直接以正确的顺序读取字节。

There's a difference between network byte order and host byte order. 网络字节顺序和主机字节顺序之间存在差异。

Typically, in C at least, you use ntohl(), ntohs() and friends to convert network byte order to your host order when reading from a socket. 通常,至少在C中,您使用ntohl(),ntohs()和朋友在从套接字读取时将网络字节顺序转换为主机顺序。

The problem is to do with the endianness of short on your system. 问题在于系统short的字节顺序。 Have a look at this question about endianness , which may provide some pointers (pun unintentional). 看看关于字节序的这个问题 ,这可能会提供一些指示(双关语无意)。

Also, I would suggest making BytesToStruct generic in the type of the struct : 另外,我建议在struct类型BytesToStruct泛型:

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

so it could be called with 所以它可以调用

BytesToStruct<S>(bArr)

rather than as at present 而不是目前

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM