c#优雅高效的读取字节数组——不安全代码(1)

科技资讯 投稿 6200 0 评论

c#优雅高效的读取字节数组——不安全代码(1)

目录
    场景
  • 如何解析字节数组到类或结构体中
    • 建立与通信协议一致的结构体
    • 使用不安全代码将字节数组映射到结构体中
  • 代码解释
      StructLayout
    • fixed

场景

在控制一些车辆进行货物搬运的业务场景下,我们需要即时的获取小车的状态数据,并且做出解析,最后进行业务处理。不管与下位机是如何通信的,最终都会读取到一个字节数组在内存中。
以TCP通讯为例子,一般会在通讯协议的报文头中定义报文的长度,从而解决一些通讯问题,如粘包等,最后读取到正文部分。

如何解析字节数组到类或结构体中

建立与通信协议一致的结构体

id motor_steps speed
1字节 2字节 1字节
    id 小车编号
  1. motor_steps 小车行走累计马达步数
  2. speed 小车当前速度

在代码中建立对应的结构体

[StructLayout(LayoutKind.Explicit)]
        public struct VehicleStatus
        {
            [FieldOffset(0)] public byte id;
            [FieldOffset(1)] public ushort motor_steps;
            [FieldOffset(3)] public byte speed;
        }
使用不安全代码将字节数组映射到结构体中
byte[] metaData = new byte[4] { 10, 88, 89, 5 }; //模拟一段报文
            unsafe
            {
                fixed (byte* metaPointer = metaData)
                {
                    VehicleStatus* status = (VehicleStatus*)metaPointer;

                    Console.WriteLine($"小车编号:{status->id}");
                    Console.WriteLine($"小车速度:{status->speed}");
                    Console.WriteLine($"小车马达步数:{status->motor_steps}");
                }
            }

代码解释

StructLayout

表示某个类或者结构体里的成员的排列方式,这里我们使用LayoutKind.Explicit精确模式,该模式必须配合FieldOffset属性一起制定字段的物理内存排列位置。

fixed

参考文档:https://learn.microsoft.com/en-us/dotnet/csharp/reference/specification/unsafe-code#fixed-and-moveable-variables

编程笔记 » c#优雅高效的读取字节数组——不安全代码(1)

赞同 (39) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽