C#之GCHandle
转载 略谈GCHandle
C# - Marshal.StructureToPtr方法简介
Marshal类 两个方法StructureToPtr和PtrToStructure实现序列化 字节 数组 转换
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace GCHandleExcerse { class Program { static void Main(string[] args) { People p1 = new People(10,180,"李白"); byte[]buff=Struct2Bytes(p1); foreach (var i in buff) { Console.Write(i+"\t"); } People p2= ByteToStruct<People>(buff); Console.WriteLine(); Console.WriteLine(p2.Age+"\t"+p2.Name+"\t"+p2.Height);//输出10 李白 180 Console.ReadKey(); } //结构体转换为byte数组 private static byte[] Struct2Bytes(object o) { // create a new byte buffer the size of your struct byte[] buffer = new byte[Marshal.SizeOf(o)]; // pin the buffer so we can copy data into it w/o GC collecting it GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);//为指定的对象分配句柄,不通过GC回收,而是通过手动释放 // copy the struct data into the buffer //StructureToPtr参数1:托管对象,包含要封送的数据。该对象必须是格式化类的实例。 //StructureToPtr参数2:指向非托管内存块的指针,必须在调用此方法之前分配该指针。 //StructureToPtr参数3:设置为 true 可在执行Marshal.DestroyStructure方法前对 ptr 参数调用此方法。请注意,传递 false 可导致内存泄漏。 // bufferHandle.AddrOfPinnedObject():检索对象的地址并返回 Marshal.StructureToPtr(o, bufferHandle.AddrOfPinnedObject(), false);//将数据从托管对象封送到非托管内存块。 // free the GC handle bufferHandle.Free(); return buffer; } //将byte数组转换为结构体 public static T ByteToStruct<T>(byte[] by) where T : struct { int objectSize = Marshal.SizeOf(typeof(T)); if (objectSize > by.Length) return default(T); // 分配内存 IntPtr buffer = Marshal.AllocHGlobal(objectSize); // 将数据复制到内存中 Marshal.Copy(by, 0, buffer, objectSize); // Push the memory into a new struct of type (T).将数据封送到结构体T中 T returnStruct = (T)Marshal.PtrToStructure(buffer, typeof(T)); // Free the unmanaged memory block.释放内存 Marshal.FreeHGlobal(buffer); return returnStruct; } } struct People { public uint Age; public ushort Height; public string Name; public People(uint age, ushort height, string name) { this.Age = age; this.Height = height; this.Name = name; } } }
4556