我有一个 C# 应用程序,它从/向 USB 读取/写入某些预定义协议的消息。所以我在这里至少有两个选择。一种是序列化/反序列化。另一个是元帅。一开始我选择了第一个选项,效果很好。但是在引入了越来越多的消息类型之后,我对每种消息类型的繁琐实现感到恼火,并且觉得 marshal 可能是更好的选择。我以前没用过元帅。这是正确的方法吗?我做了一些测试。我遇到的一个问题是当我有一个带有数组的结构时,如何写入它?比如以下:-
[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct SomeData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public sbyte[] data;
/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}
看来数据和概率都是参考,我必须新建一个对象才能使用它们,这对我来说听起来不太正确。我需要整个结构成为一个连续的内存块,我认为 new 运算符不会为我做到这一点。
任何建议都非常感谢
以下是我通过序列化的方式。
List<byte> rawData = new List<byte>();
rawData.AddRange(BitConverter.GetBytes(ProtocolVersion));
// 16 bytes for operator ID
byte[] temp = new byte[16];
Array.Copy(Encoding.ASCII.GetBytes(OperatorId), temp, OperatorId.Length > temp.Length ? temp.Length : OperatorId.Length);
rawData.AddRange(temp);
// 16 bytes for operator password
Array.Clear(temp, 0, temp.Length);
Array.Copy(Encoding.ASCII.GetBytes(OperatorPassword), temp, OperatorPassword.Length > temp.Length ? temp.Length : OperatorPassword.Length);
rawData.AddRange(temp);
以下是我通过编组完成的方式
static byte[] RawSerialize<T>(T obj)
{
if (obj == null)
{
return null;
}
int size = Marshal.SizeOf(obj);
byte[] result = new byte[size];
IntPtr buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(obj, buffer, false);
Marshal.Copy(buffer, result, 0, size);
return result;
}