【问题标题】:How to convert C# Struct to Byte Array如何将 C# 结构转换为字节数组
【发布时间】:2015-05-11 12:14:25
【问题描述】:

我有一个结构,我想通过 TCP 协议发送给 TCP 客户端,所以我想将此结构数据分配或复制到字节数组:

struct StartReadXML
   {
       public int CmdID;//3
       public char[] CmdName;//ReadXML
       public char[] Description;//Other data

   };

这里将数据分配给结构数据成员,如下所示:

StartReadXML startXML=new StartReadXML();
startXML.CmdID = 3;
startXML.CmdName = "sreedhar".ToCharArray();
startXML.Description = "Kumar".ToCharArray();

现在,我希望将它分配给一个字节数组。使用编组的方法如下:

int sizestartXML = Marshal.SizeOf(startXML);//Get size of struct data
byte[] startXML_buf = new byte[sizestartXML];//byte array & its size
IntPtr ptr = Marshal.AllocHGlobal(sizestartXML);//pointer to byte array
Marshal.StructureToPtr(startXML, ptr, true);
Marshal.Copy(ptr, startXML_buf, 0, sizestartXML);
Marshal.FreeHGlobal(ptr);

//Sending struct data  packet
stm.Write(startXML_buf, 0, startXML_buf.Length);//Modified

但是,它在 Structuretoptr 转换方法中失败。请帮助将结构数据传输为正在使用上述步骤的字节。 在此先感谢微笑| :) !!

【问题讨论】:

标签: c# arrays struct char copy


【解决方案1】:

您不能在可变大小的数组上调用StructureToPtr

这归结为,除非您知道 CmdName 的大小并声明它 - 例如,大小为 20 个字符,如下所示:

public fixed char[] CmdName[20];

Marshal 会向您打招呼,说您的结构要么是不可 blittable,要么无法获得有意义的大小。

这是 CLR 强加的要求,您无法解决。

另一种方法是使用Convert 类或序列化程序来手动转换结构的成员,但除非您事先知道这些数组的大小,否则您将无法使用StructureToPtr - string 类型也是如此,因为我假设这就是您的 char 数组将包含的内容。

考虑使用MemoryStream 并将值写入流,然后使用stream.ToArray() 发送流的内容。

【讨论】:

    【解决方案2】:

    考虑到您不能简单地将结构转换为二进制,例如:

    class StartReadXML
    {
        public int CmdID;//3
        public string CmdName;//ReadXML
        public string Description;//Other data
    }
    

    然后:

    var srx = new StartReadXML();
    srx.CmdID = 3;
    srx.CmdName = "sreedhar";
    srx.Description = "Kumar";
    
    // Example of how to Write to byte[] buffer
    
    byte[] buffer;
    
    using (var ms = new MemoryStream())
    {
        using (var bw = new BinaryWriter(ms, Encoding.UTF8))
        {
            bw.Write(srx.CmdID);
            bw.Write(srx.CmdName);
            bw.Write(srx.Description);
        }
    
        buffer = ms.ToArray();
    }
    
    // Example of how to Read from byte[] buffer
    
    var srx2 = new StartReadXML();
    
    using (var ms = new MemoryStream(buffer))
    {
        using (var br = new BinaryReader(ms, Encoding.UTF8))
        {
            srx2.CmdID = br.ReadInt32();
            srx2.CmdName = br.ReadString();
            srx2.Description = br.ReadString();
        }
    }
    

    请注意,这里我使用的是“可变长度”数据包:CmdNameDescription 的长度不是固定的(BinaryWriter/BinaryReader 通过预先添加字符串长度来处理这个问题)。

    相反的情况是当你有一个固定长度的数据包,带有固定长度的字符串。这需要完全不同的处理方式。

    【讨论】:

      猜你喜欢
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      相关资源
      最近更新 更多