热门IT资讯网

C#非托管内存的应用(二)——结构体拷贝

发表于:2024-11-25 作者:热门IT资讯网编辑
编辑最后更新 2024年11月25日,结构体的转换其实和基础类型数组转换差不多,只是结构体不能通过Marshal.Copy的方式直接转换到内存。 结构体痛byte数组的互转直接用于网络通信中还是非常方便的。1、定义结构体/// //

结构体的转换其实和基础类型数组转换差不多,只是结构体不能通过Marshal.Copy的方式直接转换到内存。 结构体痛byte数组的互转直接用于网络通信中还是非常方便的。

1、定义结构体


///    /// 测试结构体的Copy   ///    public struct TestStruct   {       public string Number;       public int[] IntMember;       public byte ByteMember;       public short ShortMember;       public override  string ToString()       {           return string.Format("Number:" + Number + " ByteMember:" + ByteMember + " ShortMember:" + ShortMember + " IntMemberCount:" + IntMember.Length);       }   }

2、Copy结构体成byte数组的方法

///        /// 将结构体直接Copy成byte数组       ///        /// 必须是结构体       /// 返回的byte数组填充,长度必须大于Marshal.SizeOf(structObj)       public static void CopyMemFromStruct(object structObj, byte[] targetData)       {           IntPtr tmptr = IntPtr.Zero;           try           {               int size = Marshal.SizeOf(structObj); // 获取结构体在内存中的大小               tmptr = Marshal.AllocHGlobal(size); // 为缓冲区分配内存空间               Marshal.StructureToPtr(structObj, tmptr, false); //Copy到分配的非托管内存中               Marshal.Copy(tmptr, targetData, 0, size);               Marshal.FreeHGlobal(tmptr);           }           catch(Exception ex)           {               if (tmptr != IntPtr.Zero)                   Marshal.FreeHGlobal(tmptr);               throw new Exception("内存操作失败:" + ex.ToString());           }       }

3、byte数组Copy成结构体的方法


///        /// 从byte数组转换成指定的结构体       ///        ///        ///        ///        ///        ///        public static void CopyMemFromBytes(byte [] sourceData, int startIndex, int length, ref object objectRef, Type type)       {           IntPtr tmptr = IntPtr.Zero;           try           {               tmptr = Marshal.AllocHGlobal(length);               Marshal.Copy(sourceData, startIndex, tmptr, length);               objectRef = Marshal.PtrToStructure(tmptr, type);               Marshal.FreeHGlobal(tmptr);           }           catch (Exception ex)           {               if (tmptr != IntPtr.Zero)                   Marshal.FreeHGlobal(tmptr);               throw new Exception("内存操作失败:" + ex.ToString());           }       }


4、测试程序


TestStruct struct1 = new TestStruct();           struct1.ByteMember = 123;           struct1.IntMember = new int[] { 1, 3, 45, 4 };           struct1.Number = "test";           struct1.ShortMember = 23241;           Console.WriteLine(struct1.ToString());           int size = Marshal.SizeOf(struct1);           byte[] testDest = new byte[size];           MemoryCopy.CopyMemFromStruct(struct1, testDest);           object struct2 = new TestStruct();           MemoryCopy.CopyMemFromBytes(testDest, 0, size,ref struct2, typeof(TestStruct));           Console.WriteLine(struct2.ToString());


0