簡體   English   中英

如何在C#中封送長度未知的字段的結構

[英]How to marshal structs with unknown length string fields in C#

我得到一個字節數組,我需要將其解組為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

我會用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位的填充字段。 誰生成了這個字節流?

但是確切的格式對於此策略而​​言並不太重要,因為您可以將ReadInt32更改為ReadInt16 ,然后對其進行重新排序,以使其正常工作。

我不喜歡序列化器屬性。 那是因為它將內部數據結構與如何交換耦合在一起。 如果您需要支持數據格式的多個版本,則此方法會中斷。

這還不是一個答案,但是是一個帶有大量可反饋代碼的問題/評論。 您如何解釋字節數組? 分解。

[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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM