2011-03-06 163 views
0

我有這個十六進制數據:C#獲取信息

byte[] data = new Byte[] { 
    0xC1, 0x3A, 0x00, 0x01, 0x5D, 0xDA, 0x47, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0x12, 0x00, 0x00, 0x00 
}; 

我有C++結構:

struct SERVICE 
{ 
    unsigned char c; 
    unsigned char size; 
    unsigned char headcode; 
    unsigned char Type; 
    unsigned short Port; 
    char ServiceName[50]; 
    unsigned short ServiceCode; 
}; 

我的問題是:如何從數據服務名稱,端口和等得到.. 。?

對不起我的英文不好

+0

這不只是英語不好....壞的問題。你有一個你想在.NET中指定的API嗎?或只是結構? – Aliostad 2011-03-06 21:10:00

+0

http://bit.ly/eO6XoJ只有這個來源 – Tomas 2011-03-06 21:22:02

回答

1

下面是做到這一點的一種方法:

struct SERVICE 
{ 
    public byte c; 
    public byte size; 
    public byte headcode; 
    public byte Type; 
    public ushort Port; 
    public string ServiceName; 
    public ushort ServiceCode; 
}; 

string GetNullTerminatedString(byte[] data, Encoding encoding) 
{ 
    int index = Array.IndexOf(data, (byte)0); 
    if (index < 0) 
    { 
     Debug.WriteLine("No string terminator found."); 
     index = data.Length; 
    } 

    return encoding.GetString(data, 0, index); 
} 

SERVICE ByteArrayToService(byte[] array, Encoding encoding) 
{ 
    using (MemoryStream stream = new MemoryStream(array)) 
    { 
     using (BinaryReader reader = new BinaryReader(stream)) 
     { 
      SERVICE service = new SERVICE(); 
      service.c = reader.ReadByte(); 
      service.size = reader.ReadByte(); 
      service.headcode = reader.ReadByte(); 
      service.Type = reader.ReadByte(); 
      service.Port = reader.ReadUInt16(); 
      service.ServiceName = GetNullTerminatedString(reader.ReadBytes(50), encoding); 
      service.ServiceCode = reader.ReadUInt16(); 
      return service; 
     } 
    } 
} 

void Main(string[] args) 
{ 
    byte[] data = new Byte[] 
    { 
     0xC1, 0x3A, 0x00, 0x01, 0x5D, 0xDA, 0x47, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0x12, 0x00, 0x00, 0x00 
    }; 

    SERVICE s = ByteArrayToService(data, Encoding.Default); 
} 

這是假設,即二進制數組使用相同的字節序的體系結構。如果不是這種情況,您可以使用MiscUtil庫中的EndianBinaryReader。

編輯:這也是一個不錯的解決方案,完全避免了讀者。您不能直接指定用於字符串的編碼,但結構的內存佈局必須與字節數組中使用的佈局相匹配。

[StructLayout(LayoutKind.Sequential)] 
struct SERVICE 
{ 
    public byte c; 
    public byte size; 
    public byte headcode; 
    public byte Type; 
    public ushort Port; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)] 
    public string ServiceName; 
    public ushort ServiceCode; 
}; 

SERVICE ByteArrayToService(byte[] array) 
{ 
    GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); 
    SERVICE service = (SERVICE)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SERVICE)); 
    handle.Free(); 
    return service; 
} 
+0

謝謝(和所有其他人)! – Tomas 2011-03-06 21:34:35

0

首先,決定您的字節編碼很少或大端。然後,解壓縮字段逐個(C示例)

struct SERVICE s; 
int i = 0; 
s.c = data[i++]; 
s.size = data[i++]; 
s.headcode = data[i++]; 
s.Type = data[i++]; 
s.Port = data[i++] << 8 | data[i++]; /* This is where endian matters */ 
memcpy(s.ServiceName, &data[i], 50); 
i += 50; 
s.ServiceCode = data[i++] << 8 | data[i++]; 

注意:這通常被寫成移動數據指針,而不是使用的「i」作爲指標,但我把它以這種形式,便於移動的到C#。

0

從這個問題,我找不到如何實現這一目標,但這是C#結構。

您可以定義結構如下圖

public struct Service 
{ 

    public byte C; 
    public byte Size; 
    public byte HeadCode; 
    public byte Type; 
    public UInt16 Port; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] 
    public byte[] values; 
    public UInt16 ServiceCode; 

}