[英]Converting struct into byte[] in c#
我在一個類中有這個結構:
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
public struct MyStruct
{
public byte StartOfText;
public byte DisableChecksum;
public byte ProtocolVersion;
public byte Code;
public Int16 Size;
public byte[] Data;
public byte EndOfText;
public MyStruct(CommandCode commandCode, string commandData)
{
this.StartOfText = 0x02;
this.DisableChecksum = 0x00;
this.ProtocolVersion = 0x35;
this.Code = (byte)commandCode;
this.Size = (Int16)commandData.Length;
this.Data = new byte[commandData.Length];
this.Data = Encoding.ASCII.GetBytes(commandData);
this.EndOfText = 0x03;
}
public byte[] ToByteArray()
{
byte[] arr = null;
IntPtr ptr = IntPtr.Zero;
try
{
Int16 size = (Int16)Marshal.SizeOf(this);
arr = new byte[size];
ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(this, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
return arr;
}
}
現在,假設我在程序中初始化該結構的新實例,執行以下操作:
Protocol.MyStruct Cmd = new Protocol.MyStruct(CommandCode.LOAD_FILE, "TEST");
byte[] StructData = Cmd.ToByteArray();
初始化時,我可以看到MyStruct.Data正在使用字符串常量(0x54,0x45,0x53,0x54)的內容正確初始化。 每個人物
但是當調用MyStruct.TiByteArray()並跟蹤數組中的值時,數據部分現在是(0xa0,0xa6,0x91和0x03)。
數組的其余部分正常,數據被正確復制。
代碼有什么問題,我錯過了什么?
這可能在某些情況下有效。 但是,數據的長度是固定的。 如果將Data定義為字符串,則可能更有用。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyStruct
{
const int ARRAY_SIZE = 100;
public byte StartOfText;
public byte DisableChecksum;
public byte ProtocolVersion;
public byte Code;
public Int16 Size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARRAY_SIZE)]
public byte[] Data;
public byte EndOfText;
public MyStruct(CommandCode commandCode, string commandData)
{
this.StartOfText = 0x02;
this.DisableChecksum = 0x00;
this.ProtocolVersion = 0x35;
this.Code = (byte)commandCode;
this.Size = (Int16)commandData.Length;
this.Data = new byte[ARRAY_SIZE];
byte[] bytes = Encoding.ASCII.GetBytes(commandData);
Array.Copy(bytes, Data, bytes.Length);
//this.Data = Encoding.ASCII.GetBytes(commandData);
this.EndOfText = 0x03;
}
public byte[] ToByteArray()
{
byte[] arr = null;
IntPtr ptr = IntPtr.Zero;
try
{
int size = Marshal.SizeOf(this);
arr = new byte[size];
ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(this, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
return arr;
}
}
在Struct聲明的頂部添加SerializableAttribute並替換ToByteArray()
方法,如下所示:
[StructLayout(LayoutKind.Sequential, Pack = 1), Serializable]
public struct MyStruct
{
public byte StartOfText;
public byte DisableChecksum;
public byte ProtocolVersion;
public byte Code;
public Int16 Size;
public byte[] Data;
public byte EndOfText;
public MyStruct(CommandCode commandCode, string commandData)
{
this.StartOfText = 0x02;
this.DisableChecksum = 0x00;
this.ProtocolVersion = 0x35;
this.Code = (byte)commandCode;
this.Size = (Int16)commandData.Length;
this.Data = new byte[commandData.Length];
this.Data = Encoding.ASCII.GetBytes(commandData);
this.EndOfText = 0x03;
}
public byte[] ToByteArray()
{
BinaryFormatter formatter = null;
MemoryStream stream = null;
byte[] arr = null;
try
{
formatter = new BinaryFormatter();
stream = new MemoryStream();
formatter.Serialize(stream, this);
arr = stream.ToArray();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
if(null != stream)
{
stream.Dispose();
}
}
return arr;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.