2011-01-30 27 views
8

Tôi nhận được một mảng byte, tôi cần phải unmarshal nó để C# struct. Tôi biết loại cấu trúc, nó có một số trường chuỗi. Các chuỗi trong mảng byte xuất hiện như sau: hai byte đầu tiên là độ dài của chuỗi, sau đó là chuỗi. Tôi không biết chiều dài của chuỗi. Tôi biết rằng mã Unicode của nó!Làm thế nào để cấu trúc nguyên soái với các trường chuỗi dài chưa biết trong C#

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

mảng byte trông giống như vậy: 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,

tôi cũng tìm thấy liên kết này với cùng một vấn đề chưa được giải quyết: loading binary data into a structure

Cảm ơn tất cả các bạn, Ofir

+0

Ofir, các chỉnh sửa được đề xuất không có nghĩa là phương tiện liên lạc, nếu bạn muốn thêm nhận xét hoặc mở rộng câu hỏi của mình, hãy thoải mái. –

+0

Làm thế nào để bạn nhận được 1 từ mảng byte? Một 'int' là 4 byte, sẽ là' {00, 00, 01, 00} ', không phải là 1. – Amy

+0

Vui lòng xem 'câu trả lời' của tôi. Tôi cần thêm thông tin. Biết mảng byte là không đủ. Cấu trúc gốc trông như thế nào? – Amy

Trả lời

0

Đây không phải là một câu trả lời (chưa) nhưng là một câu hỏi/bình luận với một số lượng khá lớn của mã cho phản hồi. Làm thế nào để bạn giải thích mảng byte của bạn? Phá vỡ nó.

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

Tôi sẽ làm điều đó với BinaryReader. Điều này sẽ đi dọc theo các dòng sau:

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; 
} 

Hãy lưu ý điều này sẽ không hoạt động trực tiếp cho ví dụ mảng byte bạn đã cung cấp. Số lượng char và trường ID không theo thứ tự nhỏ hoặc cuối kỳ chuẩn. Có thể là các trường là 16 bit và chúng được thêm vào trước với các trường đệm 16 bit. Ai đã tạo ra bytestream này?

Nhưng định dạng chính xác không quá quan trọng đối với chiến lược này, vì bạn chỉ có thể thay đổi ReadInt32 thành ReadInt16, sắp xếp lại chúng, bất cứ điều gì, để làm cho nó hoạt động.

Tôi không thích các thuộc tính bộ nối tiếp. Đó là bởi vì nó kết hợp các cấu trúc dữ liệu nội bộ của bạn với cách nó được trao đổi. Điều này xảy ra trong trường hợp bạn cần hỗ trợ nhiều phiên bản của biểu mẫu dữ liệu.

Các vấn đề liên quan