资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

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

  结构体的转换其实和基础类型数组转换差不多,只是结构体不能通过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());

标题名称:C#非托管内存的应用(二)——结构体拷贝
文章地址:http://www.cdkjz.cn/article/pgepsi.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220