我正在寻找将字节数组reinterpret_cast转换为C#结构。我已经阅读了该问题的其他几个答案,其中大多数是关于如何实现重新解释演员表的。我已经确定了一种重新解释演员表的方法,但是在我的演员表转换过程中,我得到的是单个字符而不是字符数组。
例如,我有以下对象:
public unsafe struct Establish503
{
public static Establish503 ReinterpretCast(byte[] message)
{
GCHandle handle = GCHandle.Alloc(message,GCHandleType.Pinned);
Establish503 theStruct = (Establish503)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),typeof(Establish503));
handle.Free();
return theStruct;
}
public fixed char HMACSignature[32];
public fixed char accessKey[20];
public fixed char TradingSystemName[30];
public fixed char TradingSystemVersion[10];
public fixed char TradingSystemVendor[10];
}
由于某种原因,我没有一个字节数组,而是将单个字符放在一个数组中。为什么会这样呢?这是我的本地调试窗口:
如您所见,由于某种原因,它将所有字段都视为char
而不是char[]
。
如果这不是正确的方法,那么我还有什么需要看的吗?我一直在研究Span<T>
。
编辑:与所选答案的作者Oguz Ozgul进行了进一步讨论后,确定编组将是最好的方法。后续问题是,我将如何处理嵌套结构?以下是我目前的做法。正如Oguz所提到的,对于在类外部定义并包含原始类型的结构,可以排除Marshal属性。然后可以将这些结构用作另一个结构中的字段。我已经解决了定义嵌套结构的方法,类似于定义非嵌套结构的方法。
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi,Pack = 1)]
public struct OrderMassactionReport558
{
public const int templateId_ = 558;
public const int blockSize_ = 103;
public static OrderMassactionReport558 ReinterpretCast(byte[] message)
{
GCHandle handle = GCHandle.Alloc(message,GCHandleType.Pinned);
OrderMassactionReport558 theStruct = (OrderMassactionReport558)
Marshal.PtrToStructure(handle.AddrOfPinnedObject(),typeof(OrderMassactionReport558));
handle.Free();
return theStruct;
}
[MarshalAs(UnmanagedType.U4)]
public uInt32 seqNum;
[MarshalAs(UnmanagedType.U8)]
public uInt64 uUID;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 20)]
private byte[] _senderID;
public string senderID => System.Text.Encoding.ASCII.GetString(this._senderID);
[MarshalAs(UnmanagedType.U8)]
public uInt64 partyDetailsListReqID;
[MarshalAs(UnmanagedType.U8)]
public uInt64 transactTime;
[MarshalAs(UnmanagedType.U8)]
public uInt64 sendingTimeEpoch;
[MarshalAs(UnmanagedType.U8)]
public uInt64 orderRequestID;
[MarshalAs(UnmanagedType.U8)]
public uInt64 massactionReportID;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 6)]
private byte[] _securityGroup;
public string securityGroup => System.Text.Encoding.ASCII.GetString(this._securityGroup);
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 5)]
private byte[] _location;
public string location => System.Text.Encoding.ASCII.GetString(this._location);
[MarshalAs(UnmanagedType.I4)]
public Int32NULL securityID;
[MarshalAs(UnmanagedType.U2)]
public uInt16NULL delayDuration;
[MarshalAs(UnmanagedType.U1)]
public MassactionResponse massactionResponse;
[MarshalAs(UnmanagedType.U1)]
public ManualOrdIndReq manualOrderIndicator;
[MarshalAs(UnmanagedType.U1)]
public MassactionScope massactionScope;
[MarshalAs(UnmanagedType.U1)]
public uInt8 totalAffectedOrders;
[MarshalAs(UnmanagedType.U1)]
public Booleanflag lastFragment;
[MarshalAs(UnmanagedType.U1)]
public uInt8NULL massactionRejectReason;
[MarshalAs(UnmanagedType.U1)]
public uInt8NULL marketSegmentID;
[MarshalAs(UnmanagedType.U1)]
public MassCxlReqTyp massCancelRequestType;
[MarshalAs(UnmanagedType.U1)]
public SideNULL side;
[MarshalAs(UnmanagedType.U1)]
public MassactionOrdTyp ordType;
[MarshalAs(UnmanagedType.U1)]
public MassCancelTIF timeInForce;
[MarshalAs(UnmanagedType.U1)]
public SplitMsg splitMsg;
[MarshalAs(UnmanagedType.U1)]
public BooleanNULL liquidityflag;
[MarshalAs(UnmanagedType.U1)]
public Booleanflag possRetransflag;
[StructLayout(LayoutKind.Sequential,Pack = 1)]
public struct NoAffectedOrdersEntry
{
public const int blockSize_ = 32;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 20)]
private byte[] _origCIOrdID;
public string origCIOrdID => System.Text.Encoding.ASCII.GetString(this._origCIOrdID);
public uInt64 AffectedOrderID;
public uInt32 CxlQuantity;
}
}