51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 8709|回复: 1
打印 上一主题 下一主题

C#之字节与结构体的相互转换

[复制链接]
  • TA的每日心情
    慵懒
    2018-1-3 14:03
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]测试排长

    跳转到指定楼层
    1#
    发表于 2017-3-3 09:06:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    C#使用之字节流结构体的相互转换

    本文只提供了相关方法,并没对相关函数做出解释和说明,具体函数的用法还请阅读此文的客官自行查阅百度,百度中会有详细的说明。

    一、        结构体转字节流
    1.        结构体的定义:
    1.1 函数结构体定义例子
            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct DCCS_APP_PULL_ACK_Stru
            {
                    public CSessionHead        SessionHead;
                    public UInt32        SAddress;               
                    public UInt32        TAddress;                 
                    public UInt32        UDataLength;            
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]
                    public byte[]        UData;               
                    public byte        Result;                        
            }
            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct CSessionHead
            {
                public byte Version;            
                public UInt16 Handle;           
                public UInt16 Tag;              
                public UInt32 OpCode;           
            }
    1.2 相关说明(这里只简要说明,具体用法请查阅相关资料)
    (1)[StructLayout(LayoutKind.Sequential, Pack = 1)] ,如果不加这句做限制,那么.net会对结构体布局进行自动调整,导致结构体中变量字节不对应。

    2.        结构体转换成Byte函数
    2.1 结构体转换成Byte函数
            #region 结构体转换成Byte
            public static byte[] StructToBytes(object Structname)
            {
                int size = Marshal.SizeOf(Structname);//得到结构体的大小
                IntPtr buffer = Marshal.AllocHGlobal(size); //分配结构体大小的内存空间
                try
               {
                    Marshal.StructureToPtr(Structname, buffer, false);//将结构体拷到分配好的内存空间
                    byte[] bytes = new byte[size];
                    Marshal.Copy(buffer, bytes, 0, size);//从内存空间拷到byte数组
                    return bytes;//返回byte数组
                }
                finally
                {
                    Marshal.FreeHGlobal(buffer); //释放内存空间
                }
            }
            #endregion
    2.2 结构体转换成Byte函数用法
    APP_DCCS_SUBSCRIBE_IND_Stru Stru = new APP_DCCS_SUBSCRIBE_IND_Stru() ; atc.Send(StructToBytes(Stru));//此为一个发送函数,此处只关注结构体转字节函数的用法即可。



    二.字节流转结构体:
    public byte[] recvdata;//定义一个字节型的数组
    1.字节转结构体函数:
           //将Byte转换为结构体类型
    //括号中的type为结构体,bytes参数为将要进行转换的字节流。关注函数的使用方法,对比即可有所知。
           public static object ByteToStruct(byte[] bytes, Type type)     
      {
               int size = Marshal.SizeOf(type);//获取结构体的空间大小
               if (size > bytes.Length)
               {
                   return null;
               }
               //分配结构体内存空间
               IntPtr structPtr = Marshal.AllocHGlobal(size);//开辟一个固定大小的内存空间,注意:Marshal.AllocHGlobal(Int32 cb)中的参数cb是分配的字节数
               //将byte数组拷贝到分配好的内存空间,Int32类型的两个参数都是用来限定数组的,其中一个限定开始位置,一个限定长度,其中长度是指数组元素的个数,而不是指字节数
               Marshal.Copy(bytes, 0, structPtr, size);
               //将内存空间转换为目标结构体
               object obj = Marshal.PtrToStructure(structPtr, type);
               //释放内存空间
               Marshal.FreeHGlobal(structPtr);
               return obj;
           }
    2.字节转结构体函数的用法:
      DCCS_APP_PULL_ACK_Stru PULL = new DCCS_APP_PULL_ACK_Stru();
      PULL = (DCCS_APP_PULL_ACK_Stru)ByteToStruct(atc.recvdata, typeof(DCCS_APP_PULL_ACK_Stru));//typeof获取子类的类型
    3.字节流装入的结构体:
                  [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct DCCS_APP_PULL_ACK_Stru
            {
                    public CSessionHead        SessionHead;
                    public UInt32        SAddress;               
                    public UInt32        TAddress;                 
                    public UInt32        UDataLength;        
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]//此处规定了数组的长度
                    public byte[]        UData;               
                    public byte                Result;                        
            }



    此文章为技术交流文档。如有不正确之处请指出,互相学习。
    邮箱:409393554@qq.com,如有任何疑问请发送邮件留言。
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-27 05:40 , Processed in 0.061970 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表