C#中结构体和字节数组转换

本文介绍了两种在C#中进行结构体和字节数组转换的方法:一是利用Marshal,二是使用MemoryMarshal。MemoryMarshal的使用需要注意结构体不能包含指针和引用,否则会导致运行时异常。参考了优快云博主的文章,详细探讨了转换过程及注意事项。
部署运行你感兴趣的模型镜像

方式一

 通过Marshal实现结构体和字节数组之间的转换。

using System;
using System.Runtime.InteropServices;

namespace MarshalSample
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct Message
    {
        public ushort begin;
        [MarshalAs(UnmanagedType.U1)]
        public bool result;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] detail;
        public ushort end;
    };

    class Program
    {
        public static byte[] StructToBytes<T>(T obj)
        {
            int size = Marshal.SizeOf<T>();
            byte[] bytes = new byte[size];
            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(obj, ptr, false);
            Marshal.Copy(ptr, bytes, 0, size);
            Marshal.FreeHGlobal(ptr);

            return bytes;
        }

        public static T BytesToStruct<T>(byte[] bytes)
        {
            int size = Marshal.SizeOf<T>();
            if (bytes.Length < size)
            {
                return default(T);
            }

            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.Copy(bytes, 0, ptr, size);
            T obj = Marshal.PtrToStructure<T>(ptr);
            Marshal.FreeHGlobal(ptr);

            return obj;
        }

        static void Main(string[] args)
        {
            Message msg;
            msg.begin = 0xF9F9;
            msg.result = true;
            msg.detail = new byte[2] { 0x00, 0x00 };
            msg.end = 0x9F9F;

            byte[] bytes = StructToBytes(msg);
            Message newMsg = BytesToStruct<Message>(bytes);
        }
    }
}

方式二

通过MemoryMarshal实现结构体和字节数组之间的转换。

using System;
using System.Runtime.InteropServices;

namespace MarshalSample
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct Message
    {
        public ushort begin;
        [MarshalAs(UnmanagedType.U1)]
        public bool result;
        //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        //public byte[] detail;
        public ushort end;
    };

    class Program
    {
        public static byte[] StructToBytes<T>(T obj) where T : struct
        {
            int size = Marshal.SizeOf<T>();
            byte[] bytes = new byte[size];

            T value = (T)obj;
            MemoryMarshal.Write<T>(bytes.AsSpan(), ref value);

            return bytes;
        }

        public static T BytesToStruct<T>(byte[] bytes) where T : struct
        {
            int size = Marshal.SizeOf<T>();
            if (bytes.Length < size)
            {
                return default(T);
            }

            var obj = MemoryMarshal.Read<T>(bytes);

            return obj;
        }

        static void Main(string[] args)
        {
            Message msg;
            msg.begin = 0xF9F9;
            msg.result = true;
            //msg.detail = new byte[2] { 0x00, 0x00 };
            msg.end = 0x9F9F;

            byte[] bytes = StructToBytes(msg);
            Message newMsg = BytesToStruct<Message>(bytes);
        }
    }
}

MemoryMarshal的使用有限制,结构体中不能包含指针和引用。如果打开代码中的注释后,运行时会抛出异常。详细见Microsoft文档中的说明:

public static T Read<T> (ReadOnlySpan<byte> source) where T : struct;
public static void Write<T> (Span<byte> destination, ref T value) where T : struct;

Remarks
T cannot contain pointers or references. It is checked at runtime in order to preserve type safety.

参考:

C#中结构体定义并转换字节数组 - bigfan - 博客园

C#结构体使用bool类型,并使其长度为1_sdhongjun的专栏-优快云博客

C# Marshal.SizeOf和sizeof的区别_Sakuya__的博客-优快云博客_c# marshal.sizeof

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值