C# 从 byte[] 转换为 struct。字节顺序错误
我试图在实现基于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如今,大多数处理器都使用 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.
网络字节顺序和主机字节顺序之间存在差异。
通常,至少在 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.
问题与系统上
short
的字节顺序有关。看看这个关于字节顺序的问题,它可能会提供一些提示(双关语无意)。另外,我建议将 BytesToStruct 设为 struct 类型的泛型:
调用它
这样就可以使用而不是像现在那样
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 thestruct
:so it could be called with
rather than as at present