C#中将一块数据内存强制转换为Struct结构体类型

习惯了C和C++中的简单 直接 暴力的强制类型转换,过度到C#这种更加高级的语言中有些不适应啊,高
级语言带来好处的同时(比如GC机制)也带来了一些不方便的特性,比如PC端使用串口向我发了一包完
整的结构体数据,我使用C#所做的上位机将数据都接受下来了,但解析数据是个很麻烦的过程,尤其是
数据量大的时候,此时不禁想起如果C# 能够向C或C++一样强转一块内存为结构体类型该多好

添加引用命名空间

using System.Runtime.InteropServices;

代码实现

Byte[]转Struct

      public static T ByteToStructure<T>(Byte[] dataBuffer)
        {
            object structure = null;
            int size = Marshal.SizeOf(typeof(T));
            IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
                structure = Marshal.PtrToStructure(allocIntPtr, typeof(T));
            }
            finally
            {
                Marshal.FreeHGlobal(allocIntPtr);
            }
            return (T)structure;
        }

Struct转Byte[]

 public static byte[] StructToBytes(object structObj)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(structObj);
            //创建byte数组
            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);
            //返回byte数组
            return bytes;
        }

注意Struct字节对齐

如下代码定义的Struct,4字节对齐

        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
        public struct ONE_BOARD_DATA
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            public Byte[] b1;
            public Byte IOStatus;
            public Byte bHint;//1:debug message 0:none
            public Byte HintMsgLen;
            public UInt16 HintReserved; // u16  Hint保留位
            public UInt32 crc; //u32

        };

Guess you like

Origin blog.csdn.net/weixin_42314225/article/details/98681922