C#中结构体和字节数组互相转换是常见的操作,结构体可以用来表示数据的存储,字节数组可以用来将数据在不同计算机或程序之间传输。以下是实现该操作的攻略。
1. 结构体与字节数组的转换
1.1 将结构体转换为字节数组
将结构体转换成字节数组需要用到C#中的Marshal类和SizeOf方法。SizeOf方法可以得到结构体的大小,Marshal类提供了各种Marshaling操作,其中有一个结构体转换成字节数组的方法StructToBytes。
下面是一个示例代码:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Person
{
public int age;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string name;
}
public static byte[] StructToBytes(Person person)
{
byte[] byteArray = new byte[Marshal.SizeOf(person)];
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(person));
Marshal.StructureToPtr(person, ptr, true);
Marshal.Copy(ptr, byteArray, 0, Marshal.SizeOf(person));
Marshal.FreeHGlobal(ptr);
return byteArray;
}
结构体Person中包含年龄和姓名两个字段。在StructToBytes方法中,首先创建了一个字节数组,并使用SizeOf方法获取结构体Person的实际大小。然后,使用Marshal.AllocHGlobal方法在堆上申请一块内存以存放结构体Person,转换后再通过Marshal.Copy方法将指针指向的内存块中的数据拷贝到byteArray中,最后释放内存。该方法的调用结果为.
Person person = new Person
{
age = 27,
name = "Tommy"
};
byte[] byteArray = StructToBytes(person);
foreach (byte b in byteArray)
{
Console.Write(b + " ");
}
// Output: 27 0 0 0 84 111 109 109 121 0 0 0 0 0 0 0 0 0 0 0
1.2 将字节数组转换为结构体
将字节数组转换成结构体也需要用到Marshal类和SizeOf方法。Marshal提供了一个方法BytsToStructure实现将数组转换为结构体。
下面是一个示例代码:
public static Person BytesToStruct(byte[] byteArray)
{
IntPtr ptr = Marshal.AllocHGlobal(byteArray.Length);
Marshal.Copy(byteArray, 0, ptr, byteArray.Length);
Person person = (Person)Marshal.PtrToStructure(ptr, typeof(Person));
Marshal.FreeHGlobal(ptr);
return person;
}
在BytesToStruct方法中,首先使用Marshal.AllocHGlobal方法申请一块内存,大小和byteArray数组一样。然后使用Marshal.Copy方法将byteArray数组中的数据复制到申请到的内存中,将该内存的地址转换为结构体对象,然后再调用Marshal.FreeHGlobal方法释放内存。该方法的调用结果如下:
Person person = BytesToStruct(byteArray);
Console.WriteLine(person.age); // Output: 27
Console.WriteLine(person.name); // Output: Tommy
2. 示例应用:发送结构体数据
以下是一个应用示例,该应用可以向服务器发送一个包含结构体数据的网络包。
2.1 自定义结构体
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PlayerInfo
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string playerName;
public int level;
public float hp;
public float mp;
}
在该示例中,我们定义了一个PlayerInfo结构体,包含玩家名字、等级、生命值和魔法值等数据。
2.2 使用Socket发送数据
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint endPoint = new IPEndPoint(ip, 8888);
client.Connect(endPoint);
PlayerInfo playerInfo = new PlayerInfo
{
playerName = "Tommy",
level = 10,
hp = 100.0f,
mp = 50.0f,
};
byte[] dataBytes = StructToBytes(playerInfo);
client.Send(dataBytes);
client.Close();
在该示例中,我们创建了一个Socket对象,并且连接到了服务器,然后创建了一个PlayerInfo结构体对象,使用之前的方法将其转换为字节数组dataBytes,并最后使用Socket发送该数据包。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中结构体和字节数组转换实现 - Python技术站