c#优雅高效的读取字节数组——不安全代码(1)
2023/5/24 18:22:08
本文主要是介绍c#优雅高效的读取字节数组——不安全代码(1),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在开发上位机的经历中,会有很多需要和下位机交互通信的场景,大多数都会定义一个和硬件的通信协议,最终在上位机代码中的形式其实就是符合通信协议的字节数组。
- 场景
-
如何解析字节数组到类或结构体中
- 建立与通信协议一致的结构体
- 使用不安全代码将字节数组映射到结构体中
-
代码解释
- StructLayout
- fixed
场景
在控制一些车辆进行货物搬运的业务场景下,我们需要即时的获取小车的状态数据,并且做出解析,最后进行业务处理。不管与下位机是如何通信的,最终都会读取到一个字节数组在内存中。
以TCP通讯为例子,一般会在通讯协议的报文头中定义报文的长度,从而解决一些通讯问题,如粘包等,最后读取到正文部分。
如何解析字节数组到类或结构体中
建立与通信协议一致的结构体
比如通讯协议的正文格式定义如下:
id | motor_steps | speed |
---|---|---|
1字节 | 2字节 | 1字节 |
- id 小车编号
- motor_steps 小车行走累计马达步数
- 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
用来钉住可移动变量,确保GC在执行期间对不会重新定位或释放包含对象实例,如果位置变了或者被释放了,谁还管你的非托管的指针对象呢?这边字节数组肯定是一个可移动变量了。
参考文档:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/unsafe-code#fixed-and-moveable-variables
这篇关于c#优雅高效的读取字节数组——不安全代码(1)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#