使用基于头类型的字节数组初始化struct

时间:2014-03-06 18:36:20

标签: c# struct bytearray

我的文件中有几个结构。我想传递一个字节数组并初始化结构。我已经尝试过struct to byte array conversion,反之亦然但是我遇到的错误就像“试图读取或写入受保护的内存”。所以我认为传递字节数组来初始化结构可能更有效。我的问题是结构的一部分依赖于第一字节类型。那么我该如何为它分配另一个结构呢?

这是代码:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct Payload
{
    MessageTypeID ID1;   
    MessageTypeID ID2;  
    Byte[] PayloadData; 

    public Payload(byte[] payloadArray)
    {
        this.ID1 = (MessageTypeID) payloadArray[0];
        this.ID2 = (MessageTypeID) payloadArray[1];

        switch (this.ID1)
        {
            case MessageTypeID.TEMPERATURE:
                byte[] tempPayloadArray = new byte[payloadArray.Length - 2];
                Temperature temp = new Temperature(Array.Copy(payloadArray,2,tempPayloadArray,0,payloadArray.Length - 2);
                this.PayloadData = temp;  <== ERROR: Cannot convert Temperature to byte[]
                break;
            case MessageTypeID.LEVEL:
            .......
        }
    }
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Temperature
{
    Byte LocalTemp;         
    Int16 ExternalTemp1;                                  
    Int16 ExternalTemp2;   

    public Temperature(byte[] tempArray)
    {
        this.LocalTemp = tempArray[0];
        this.ExternalTemp1 = tempArray[1];
        this.ExternalTemp2 = tempArray[2];
    }
}
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Level
{
    Byte FluidLevel;        
    Int16 FreshnessTimer;   
    Byte CalibrationChannelReading; 

    public Level(byte[] levelArray)
    {
        this.FluidLevel = levelArray[0];
        this.FreshnessTimer = BitConverter.ToInt16(levelArray, 1);
        this.CalibrationChannelReading = levelArray[3];
    }
}

1 个答案:

答案 0 :(得分:1)

不要自己动手:使用基础设施.Net和CLR为您提供。

如果您需要与非托管代码进行互操作,则需要了解P / Invoke和编组:

如果您要与其他托管代码进行互操作,则需要阅读serialization。更多

您可以使用库存二进制序列化,也可以自己滚动。在任何一种情况下,您都希望对象为ISerializable,这只需要实现一种方法将对象序列化为字节流:void GetObjectData( SerializationInfo info , StreamingContext context )

并且[暗示]一个相应的构造函数,用于将字节流反序列化为具有签名constructor( SerializationInfo information, StreamingContext context)的对象实例。

例如:

[Serializable]
public class Widget : ISerializable
{
  public Widget( SerializationInfo serializationInfo , StreamingContext context )
  {
    // your rehydration logic here
  }
  public void GetObjectData( SerializationInfo info , StreamingContext context )
  {
    // your dehydration logic here
  }
  ...
}