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

发布于 2024-09-14 16:11:09 字数 1411 浏览 9 评论 0原文

我试图在实现基于 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 到 byte[] 是一样的。 ushort 的 2 个字节被反转。 我该如何解决这个问题?

I was trying to use a struct to parse socket data when implement a UDP based protocol.
And I searched and I can use these 2 functions to convert between byte[] and 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. The 2 bytes of ushort are reversed.
How do I solve this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

林空鹿饮溪 2024-09-21 16:11:09

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

Frank 提到的 ntohs() 的 .Net 等效项位于(奇怪)System.Net.IPAddress.NetworkToHostOrder()< /code>

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

Most processors these days use Little-Endian byte ordering (Least significant byte comes first). Network byte ordering is traditional Big-Endian, so you usually need to mirror the byte order. You can check the endianness of the system with System.BitConverter.IsLittleEndian

The .Net equivalent of ntohs() Frank mentioned is located (oddly) at 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.

━╋う一瞬間旳綻放 2024-09-21 16:11:09

网络字节顺序和主机字节顺序之间存在差异。

通常,至少在 C 语言中,当从套接字读取数据时,您可以使用 ntohl()、ntohs() 等将网络字节顺序转换为主机顺序。

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.

风透绣罗衣 2024-09-21 16:11:09

问题与系统上 short 的字节顺序有关。看看这个关于字节顺序的问题,它可能会提供一些提示(双关语无意)。

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

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

调用它

BytesToStruct<S>(bArr)

这样就可以使用而不是像现在那样

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

The problem is to do with the endianness of short on your system. 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:

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))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文