C#结构体,字节数组等

[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MIBP_ItemInfo{
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]  //这里换成你实际的常量
   public string ItemSN;
   public uint   ItemCount;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]  //这里换成你实际的常量
   public string ItemUnit;
}
 
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MIBP_BindSetInfo{
   [ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]  //这里换成你实际的常量
   public byte[] RFIDSN;
   public byte   ItemTypeCount;
   public IntPtr ItemInfo;
}
 
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MIBP_ItemInfo{
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]  //这里换成你实际的常量
   public string ItemSN;
   public uint   ItemCount;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]  //这里换成你实际的常量
   public string ItemUnit;
}
 
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MIBP_BindSetInfo{
   [ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]  //这里换成你实际的常量
   public byte[] RFIDSN;
   public byte   ItemTypeCount;
   public IntPtr ItemInfo;
}
 
 

在C#进行UDP或者TCP/IP通信时,经常要用到byte数组来传递信息。一开始,我是使用BitConverter和Encoding来进行转换。后来经过大神指导,其实一切不必那么麻烦。只需将要发送的信息封装成结构体,使用C#自带的一个转换类便可轻松搞定。

首先建立一个结构体

//必须引用的库
using System.Runtime.InteropServices;

namespace Test
{
    [StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi,Pack=1)]
    struct SensorHeadInfo
    {
        public uint cmdId;
        [MarshalAs(UnmanagedType.ByValArray,SizeConst=5)]
        public byte[] time_t;
        public ushort msgLength;
        public byte errorFlag;
        public byte moduleId;
    }
}

其次建立转换类

 

using System;
using System.Runtime.InteropServices;

namespace Test
{
    class MessageSwitch
    {
        /// <summary>
        /// 将结构体转换为byte数组
        /// </summary>
        /// <typeparam name="T"> 泛型T</typeparam>
        /// <param name="structObj">结构体对象</param>
        /// <returns></returns>
        public static byte[] StructToBytes<T>(T structObj) where T : struct
        {
            // 获取结构体对象的字节数
            int size = Marshal.SizeOf(structObj);
            byte[] bytes = new byte[size];
            // 申请内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体内容拷贝到上一步申请的内存空间
            Marshal.StructureToPtr(structObj, structPtr, false);
            // 将数据拷贝到byte数组
            Marshal.Copy(structPtr, bytes, 0, size);
            // 释放申请的内存
            Marshal.FreeHGlobal(structPtr);

            return bytes;
        }

        public static T BytesToStruct<T>(byte[] bytes) where T:struct
        {
            T obj = new T();

            int size = Marshal.SizeOf(obj);

            // 如果结构体对象的字节数大于所给byte数组的长度,则返回空
            if (size > bytes.Length)
            {
                return (default(T));
            }

            IntPtr structPtr = Marshal.AllocHGlobal(size);
            Marshal.Copy(bytes, 0, structPtr, size);
            object tempObj = Marshal.PtrToStructure(structPtr, obj.GetType());
            Marshal.FreeHGlobal(structPtr);

            return (T)tempObj; 
        }
    }
}
使用方法如下

 

 

 public static byte[] getSensorHeaserInfo()
        {
            Random random = new Random(DateTime.Now.Millisecond + DateTime.Now.Second);
            SensorHeadInfo headerInfo = new SensorHeadInfo();

            int index = random.Next(0, moduleTypeVal.Count);

            headerInfo.cmdId = 12;
            headerInfo.time_t = new byte[5];
            headerInfo.moduleId = 13;

            // get message length
            headerInfo.msgLength = (ushort)13;
            // create message bytes array
            byte[] res = new byte[13];
 <span style="white-space:pre">	</span>    MessageSwitch.StructToBytes<SensorHeadInfo>(headerInfo).CopyTo(res, 0);

            return res;
        }
至于字节数转换结构体则如下

 

 

byte[] msg = m_listenUdp.Receive(ref remoteEndPoint);
SensorHeadInfo headerInfo = MessageSwitch.BytesToStruct<SensorHeadInfo>(msg);
接收到消息后直接转换
posted @ 2020-02-24 20:48  老猫88  阅读(826)  评论(0)    收藏  举报