Я пишу код для разбора пакетов.
Я хочу изменить ссылочный адрес массива, но я не знаю, как изменить ссылочный адрес без использования указателя.
Если я скопирую часть массива, я думаю, что он замедлится. Если я использую указатель, это будет небезопасно.
Ниже приведен код, который я пишу.
public class Datagrams : LinkedList<DatagramPacket>
{
public Datagrams(byte[] RowData) : base()
{
AddLast(new DatagramPacket(RowData));
while(Last.Value.header.Length.LastIndicator)
{
///////////////////////////////////////////
//I want do that. But this is unsafe code//
///////////////////////////////////////////
AddLast(new DatagramPacket( RowData + sizeof[Last.Value] ));
}
}
}
public class DatagramPacket : Packet
{
public enum DatagramCmd : Byte
{
NOP = 0x0,
APRD = 0x1,
APWR = 0x2,
APRW = 0x3,
FPRD = 0x4,
FPWR = 0x5,
FPRW = 0x6,
BRD = 0x7,
BWR = 0x8,
BRW = 0x9,
LRD = 0xA,
LWR = 0xB,
LRW = 0xC,
ARMW = 0xD,
FRMW = 0xE
}
[StructLayout(LayoutKind.Explicit)]
public struct DatagramAddr
{
[MarshalAs(UnmanagedType.U4), FieldOffset(0)]
public UInt32 LogicalAddr;
[MarshalAs(UnmanagedType.U2), FieldOffset(0)]
public UInt16 SlaveAddr;
[MarshalAs(UnmanagedType.U2), FieldOffset(2)]
public UInt16 OffsetAddr;
}
public struct DatagramLength
{
[MarshalAs(UnmanagedType.U2)]
public UInt16 bits;
public int Length { get => bits & 0x07FF; }
public bool Valid { get => (bits & 0x0380) == 0; }
public bool RoundTrip { get => (bits & 0x4000) != 0; }
public bool LastIndicator { get => (bits & 0x8000) != 0; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DatagramHeader
{
[MarshalAs(UnmanagedType.U1)]
public DatagramCmd Cmd;
[MarshalAs(UnmanagedType.U1)]
public Byte Index;
[MarshalAs(UnmanagedType.Struct)]
public DatagramAddr Addr;
[MarshalAs(UnmanagedType.Struct)]
public DatagramLength Length;
[MarshalAs(UnmanagedType.U2)]
public UInt16 Interrupt;
}
public DatagramHeader header;
public UInt16 wc; //Working Count
public DatagramPacket(byte[] RowData) : base(RowData)
{
header = new DatagramHeader();
GCHandle handle = GCHandle.Alloc(RowData, GCHandleType.Pinned);
try
{
header = (DatagramHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DatagramHeader));
}
finally
{
handle.Free();
}
body = new byte[header.Length.Length];
Buffer.BlockCopy(RowData, Marshal.SizeOf<DatagramHeader>(), body, 0, body.Length);
wc = BitConverter.ToUInt16(RowData, Marshal.SizeOf<DatagramHeader>() + body.Length);
}
public override Packet Parse()
{
throw new NotImplementedException();
}
}
Есть ли способ изменить ссылку без использования указателя?