2011-03-06 167 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; 

}