Tôi nhận được một mảng byte từ một socket và cấu trúc của các byte đơn giản là một mảng char lớn của các chuỗi có chiều rộng cố định. Trong một số trường hợp, trường cuối cùng là động (thay vì chiều dài cố định) và tôi đang cố Soạn các byte thành một cấu trúc. Tôi đã đọc rằng mảng char biến dài cần phải là IntPtr, nhưng tôi đã không tìm ra cách so sánh nó với các byte còn lại. Tôi cũng đã đọc trong một số bài viết mà tôi có thể cần một cấu trúc thứ hai, nhưng vẫn không thể tìm ra cách So sánh nó một cách chính xác.mảng byte [] để cấu trúc với mảng độ dài biến
Dưới đây là một ví dụ site
cách thích hợp để đối phó với mảng char chiều dài thay đổi trong cấu trúc là gì?
Các struct:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Header
{
#region private member fields
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f5;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f6;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private char[] _f7;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
private char[] _f8;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
private char[] _f9;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private char[] _f10;
// how would this get filled with a char[] array from the byte array?
public IntPtr VariableLengthData;
#endregion
}
Chức năng:
public static Header FromArray(byte[] array)
{
IntPtr buff = IntPtr.Zero;
try
{
int objsize = Marshal.SizeOf(typeof(Header));
buff = Marshal.AllocHGlobal(objsize);
Marshal.Copy(array, 0, buff, objsize);
var result = (Header)Marshal.PtrToStructure(buff, typeof(HostHeader));
// the variable length data needs to be filled in somehow
// but also note that an extra 4 bytes was added to the size
// of the struct with the IntPtr
if(objsize < array.Length)
{
Marshal.Copy(array, array.Length - objsize, result.VariableLengthData, array.Length - objsize);
}
return result;
}
finally
{
if (buff != IntPtr.Zero)
{
Marshal.FreeHGlobal(buff);
buff = IntPtr.Zero;
}
}
}
này hoạt động - nhưng bây giờ Marshal.SizeOf (headerObj) cho biết đó là nhỏ hơn nó thực sự là khi tôi cố gắng chuyển đổi nó trở lại mảng byte []. Khác hơn thế, bất cứ điều gì sai với giải pháp này?
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] Field1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] Field2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] Field3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] Field4;
}
public static Header DeserializeHeader(byte[] data)
{
int objsize = Marshal.SizeOf(typeof(Header));
IntPtr buff = Marshal.AllocHGlobal(objsize);
Marshal.Copy(data, 0, buff, objsize);
var header = (Header)Marshal.PtrToStructure(buff, typeof(Header));
Marshal.FreeHGlobal(buff);
// resize Field4 to hold all the remaining bytes
if(objsize < data.Length)
{
header.Field4 = Encoding.ASCII.GetChars(data, objsize - header.Field4.Length, data.Length - objsize - header.Field4.Length);
}
return header;
}
Bạn nên nói lại và đặt câu hỏi thực tế. –
mảng + 160 là phần còn lại của dữ liệu của bạn. 'Encoding.ASCII.GetString (mảng, 160, mảng.Length-160)' – EZI
@EZI - đó là chính xác. Nếu mảng byte lớn hơn 160, mọi thứ khác là trường có độ dài thay đổi. –