我有这个十六进制数据:
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:
struct SERVICE
{
unsigned char c;
unsigned char size;
unsigned char headcode;
unsigned char Type;
unsigned short Port;
char ServiceName[50];
unsigned short ServiceCode;
};
我的问题是:如何从数据ServiceName,端口等获取......?
抱歉我的英文不好
答案 0 :(得分: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);
}
这假定二进制数组使用与您的体系结构相同的Endianess。如果不是这种情况,您可以使用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;
}
答案 1 :(得分: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#。
答案 2 :(得分: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;
}