8

我得到一个字节数组,我需要将它解组为 C# 结构。我知道结构的类型,它有一些字符串字段。字节数组中的字符串如下所示:前两个字节是字符串的长度,然后是字符串本身。我不知道字符串的长度。我知道它的Unicode!

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class User
{
  int Id;//should be 1
  String UserName;//should be OFIR
  String FullName;//should be OFIR
}

字节数组如下所示:00,00,01,00, 00,00,08,00, 4F,00,46,00,49,00,52,00, 00,00,08,00, 4F,00 ,46,00,49,00,52,00,

我还发现这个链接有同样的问题未解决: 将二进制数据加载到结构中

谢谢大家, Ofir

4

2 回答 2

3

我会用BinaryReader. 这将遵循以下原则:

Foo ReadFoo(Byte[] bytes)
{
     Foo foo = new Foo();
     BinaryReader reader = new BinaryReader(new MemoryStream(bytes));
     foo.ID = reader.ReadUInt32();
     int userNameCharCount = reader.ReadUInt32();
     foo.UserName = new String(reader.ReadChars(userNameCharCount));

     int fullNameCharCount = reader.ReadUInt32();
     foo.FullName = new String(reader.ReadChars(fullNameCharCount));
     return foo;
}

请注意,这不适用于您提供的字节数组示例。字符数和 ID 字段不是标准的小端或大端顺序。这些字段可能是 16 位的,并且它们前面有 16 位填充字段。谁生成了这个字节流?

但是确切的格式对于这个策略来说并不太重要,因为你可以改变ReadInt32ReadInt16,重新排序它们,无论如何,让它工作。

我不喜欢序列化器属性。那是因为它将您的内部数据结构与它的交换方式相结合。如果您需要支持数据格式的多个版本,这会中断。

于 2011-02-04T21:09:21.170 回答
0

这不是一个答案(还),而是一个带有大量反馈代码的问题/评论。你如何解释你的字节数组?把它分解。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct Foo
{
    public int id;

    //[MarshalAs(UnmanagedType.BStr)]
    //public string A;

    //[MarshalAs(UnmanagedType.BStr)]
    //public string B;
}

static void Main(string[] args)
{
    byte[] bits = new byte[] {
        0x00, 0x00, 
        0x01, 0x00, 
        0x00, 0x00, 
        0x08, 0x00,     // Length prefix?               
        0x4F, 0x00,     // Start OFIR?
        0x46, 0x00, 
        0x49, 0x00,     
        0x52, 0x00,     
        0x00, 0x00, 
        0x08, 0x00,     // Length prefix?
        0x4F, 0x00,     // Start OFIR?
        0x46, 0x00, 
        0x49, 0x00, 
        0x52, 0x00 };   

    GCHandle pinnedPacket = GCHandle.Alloc(bits, GCHandleType.Pinned);
    Foo msg = (Foo)Marshal.PtrToStructure(
        pinnedPacket.AddrOfPinnedObject(),
        typeof(Foo));
    pinnedPacket.Free();
}
于 2011-02-01T21:58:14.367 回答