温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2020-04-06 16:23:29 来源:网络 阅读:2487 作者:andwp 栏目:编程语言

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

1、定义结构体


/// <summary>
   /// 测试结构体的Copy
   /// </summary>
   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数组的方法

/// <summary>
       /// 将结构体直接Copy成byte数组
       /// </summary>
       /// <param name="structObj">必须是结构体</param>
       /// <param name="targetData">返回的byte数组填充,长度必须大于Marshal.SizeOf(structObj)</param>
       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成结构体的方法


/// <summary>
       /// 从byte数组转换成指定的结构体
       /// </summary>
       /// <param name="sourceData"></param>
       /// <param name="startIndex"></param>
       /// <param name="length"></param>
       /// <param name="objectRef"></param>
       /// <param name="type"></param>
       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());


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI