[海康开发笔记]将内存片段格式化为C#类对象时需要注意对象的字段顺序

将内存片段byte[] data 格式化为结构或类实例时,结构/类的属性或字段定义顺序将影响格式化结果。

如海康设备向注册中心发送的数据表中,包头信息类的定义:

/// 
/// 设备向服务器:MsgRetHeader 
/// 
[StructLayout(LayoutKind.Sequential)]
public class MsgRetHeader : CmdHeader
{
    /// 
    /// 海康与平台厂家协商定义的标记,此标记在前端PU与平台对接中保持一致,不能单方面修改,现阶段信令部分为0x53584C54,码流部分为0x53585354
    /// 
    public uint tag;

    /// 
    /// 前端PU接入CMS的设备标识(简称PUID),由平台分配,并确保前端PU唯一
    /// 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string deviceId;

    /// 
    /// 根据不同的功能定义使用,不使用时默认为0,与通道相关的码流和参数配置时候需填写chan字段
    /// 
    public uint chan;

    /// 
    /// 根据不同的功能定义使用,不使用时默认为0
    /// 
    public uint devideType;

    /// 
    /// XML封装的消息体内容长度,用于传输中消息数据的接收,以字节计算,若此值为0,表示XML内容不存在
    /// 
    public uint streamLength;

    /// 
    /// 保留字段
    /// 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string res;
}

MsgRetHeader 类的各个字段的定义顺序必须和设备发送数据包时所用的结构体中各字段的定义顺序一致(数据包结构体是C++程序,由TCP发送),满足该条件后即可使用如下方法将byte[]转化为C#中的类实例:

/// 
/// 将byte[]转换为结构体
/// 
/// 
/// 
/// 
  
  
public static object BytesToStruct(byte[] bytes, Type strcutType)
{
    int size = Marshal.SizeOf(strcutType);
    IntPtr buffer = Marshal.AllocHGlobal(size);
    try
    {
        Marshal.Copy(bytes, 0, buffer, size);
        return Marshal.PtrToStructure(buffer, strcutType);
    }
    finally
    {
        Marshal.FreeHGlobal(buffer);
    }
}

如果交换了字段定义顺序,则转化出来的类实例字段值将产生逻辑错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值