1

我有一个 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;
    }
4

1 回答 1

0

看来我只需要像下面这样新建一个数组就可以了。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class SomeData
{
    /// char[15]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public byte[] data = new byte[15];

    /// int[15]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob = new int[15];
}
于 2013-06-26T01:46:34.317 回答