C#将字节解析为struct sequential

时间:2017-03-08 22:25:33

标签: c# arrays struct

我尝试将一个字节数组解析为struct但它不能用于Sequential。 Sequential结构中的值是错误的,但它与Explicit结构一致吗?我需要顺序字节数组没有固定长度。 DwLength字段是数据字段的大小。

  • MessageType 128(Sequential 128)
  • DwLength 20(Sequential 33554432)
  • Slot 0(Sequential 0)
  • Seq 0(顺序0)
  • 状态2(连续59)
  • 错误0(顺序143)
  • ChainParameter 0(Sequential 128)

测试代码

var bytes = new byte[] { 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3B, 0x8F, 0x80, 0x01, 0x80, 0x4F, 0x0C, 0xA0, 0x00, 0x00, 0x03, 0x06, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x68 };

var result1 = GetStruct<RdrToPcDataBlock1>(bytes);
var result2 = GetStruct<RdrToPcDataBlock2>(bytes);

struct RdrToPcDataBlock Sequential

[StructLayout(LayoutKind.Sequential)]
public struct RdrToPcDataBlock1
{
    public byte MessageType;
    public int DwLength;
    public byte Slot;
    public byte Seq;
    public byte Status;
    public byte Error;
    public byte ChainParameter;
    [MarshalAs(UnmanagedType.ByValArray)]
    public byte[] Data;
}

struct RdrToPcDataBlock明确

[StructLayout(LayoutKind.Explicit)]
public struct RdrToPcDataBlock2
{
    [FieldOffset(0)]
    public byte MessageType;
    [FieldOffset(1)]
    public int DwLength;
    [FieldOffset(5)]
    public byte Slot;
    [FieldOffset(6)]
    public byte Seq;
    [FieldOffset(7)]
    public byte Status;
    [FieldOffset(8)]
    public byte Error;
    [FieldOffset(9)]
    public byte ChainParameter;
    [FieldOffset(10)]
    public byte Data;
}

GetStruct

public T GetStruct<T>(byte[] bytes)
{
    try
    {
        var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var item = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        handle.Free();
        return item;
    }
    catch
    {
        return default(T);
    }
}

1 个答案:

答案 0 :(得分:6)

执行与[StructLayout(LayoutKind.Sequential)]相同的[StructLayout(LayoutKind.Sequential, Pack=0)]时,[StructLayout(LayoutKind.Sequential, Pack=1)]将使用默认打包来处理进程的位数(对于32位为4,对于64位为8)。要获得您想要的行为,您需要通过设置library("pacman") pacman::p_load("RJDBC") pacman::p_load("dplyr") # Downloading Athena driver to the working directory URL <- 'https://s3.amazonaws.com/athena-downloads/drivers/AthenaJDBC41-1.0.0.jar' fil <- basename(URL) if (!file.exists(fil)) download.file(URL, fil) # Defining driver drv <- JDBC(driverClass="com.amazonaws.athena.jdbc.AthenaDriver", fil, identifier.quote="'")

明确表示您不需要任何填充

UPDATE:您仍然会遇到可变长度字节数组的问题。请参阅comment by Jean-Bernard Pellerin

  

您必须使用自定义编组程序。否则你无法处理可变长度数组。这是一个例子:https://stackoverflow.com/a/38884095/103959