C#非托管内存的应用(二)——结构体拷贝-创新互联

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

睢县网站建设公司创新互联公司,睢县网站设计制作,有大型网站制作公司丰富经验。已为睢县上1000家提供企业网站建设服务。企业网站搭建\成都外贸网站制作要多少钱,请找那个售后服务好的睢县做网站的公司定做!

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());

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


分享文章:C#非托管内存的应用(二)——结构体拷贝-创新互联
分享链接:http://pwwzsj.com/article/dssjds.html