2011-01-30 8 views
8

バイトの配列を取得します。これをC#structにアンマーシャリングする必要があります。 私は構造体の型を知っています、それはいくつかの文字列フィールドを持っています。 バイト配列の文字列は次のようになります。最初の2バイトは文字列の長さ、次に文字列自体です。 文字列の長さを知りません。 私はそのUnicodeを知っています!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 
} 

バイト配列はそうのようになります。 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、

私も同じ問題を持つこのリンクは未解決のが見つかりました: loading binary data into a structure

はあなたのすべてをありがとう、 Ofir

+0

Ofirは、コメントを追加したり、質問を自由に展開したい場合は、提案された編集内容をコミュニケーション手段として意味しません。 –

+0

バイト配列から1をどのように取得しますか? 'int'は4バイトで、' {00、00、01、00} 'です。これは1ではありません。 – Amy

+0

私の'答え 'を見てください。私はより多くの情報が必要です。バイト配列を知るだけでは不十分です。ネイティブ構造はどのように見えますか? – Amy

答えて

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

これは、指定したバイト配列の例では直接動作しませんのでご注意ください。 char countsとIDフィールドは標準のリトルエンディアンまたはビッグエンディアンの順序ではありません。フィールドは16ビットであり、16ビットのパディングフィールドが前に付いていることがあります。誰がこのbytestreamを生成しましたか?

ReadInt32ReadInt16に変更するだけで、正確なフォーマットはそれほど重要ではありません。

私はシリアライザの属性を気にしません。これは、内部データ構造がどのように交換されるかを結合するためです。これは、データ形式の複数のバージョンをサポートする必要がある場合に備えて破損します。

関連する問題