【发布时间】:2013-06-21 01:43:48
【问题描述】:
我有一个 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;
}
【问题讨论】:
-
有一些方法可以以通用的方式进行序列化和反序列化,只需很少的仪式。你能告诉我们你是怎么做的吗?
-
另外,如果您能告诉我们更多关于为什么序列化不适合您,以及为什么您认为编组可能会更好,那就太好了。
-
我已经添加了代码示例。我没有说它对我不起作用。只是因为我必须解析不同类型的消息。
-
编组示例看起来不错。这基本上就是我在我目前正在编写的程序中所做的事情。那么你有什么疑问呢?
-
我不熟悉编组,不安全的代码让我很紧张,尽管我是一名 C++ 程序员。在我帖子的后半部分,我说我在访问数组时遇到了一些问题。
标签: c# arrays serialization marshalling