经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
c#优雅高效的读取字节数组——不安全代码(1)
来源:cnblogs  作者:BruceNeter  时间:2023/5/26 9:56:10  对本文有异议

在开发上位机的经历中,会有很多需要和下位机交互通信的场景,大多数都会定义一个和硬件的通信协议,最终在上位机代码中的形式其实就是符合通信协议的字节数组。

场景

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

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

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

比如通讯协议的正文格式定义如下:

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

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

  1. [StructLayout(LayoutKind.Explicit)]
  2. public struct VehicleStatus
  3. {
  4. [FieldOffset(0)] public byte id;
  5. [FieldOffset(1)] public ushort motor_steps;
  6. [FieldOffset(3)] public byte speed;
  7. }
使用不安全代码将字节数组映射到结构体中
  1. byte[] metaData = new byte[4] { 10, 88, 89, 5 }; //模拟一段报文
  2. unsafe
  3. {
  4. fixed (byte* metaPointer = metaData)
  5. {
  6. VehicleStatus* status = (VehicleStatus*)metaPointer;
  7. Console.WriteLine($"小车编号:{status->id}");
  8. Console.WriteLine($"小车速度:{status->speed}");
  9. Console.WriteLine($"小车马达步数:{status->motor_steps}");
  10. }
  11. }

代码解释

StructLayout

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

fixed

用来钉住可移动变量,确保GC在执行期间对不会重新定位或释放包含对象实例,如果位置变了或者被释放了,谁还管你的非托管的指针对象呢?这边字节数组肯定是一个可移动变量了。

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

原文链接:https://www.cnblogs.com/qwqwQAQ/p/17428679.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号