How to parse an array of bytes into an object?

I read binary data (through a network stream or from files) that is predetermined several years ago. I am currently reading this data, reading it into an array of bytes, and then converting the array to the fields I need with System.BitConverter. Needless to say, this is temporary consumption and error prone.

I would like to use ISerializable, but I do not see how this can be implemented for a predefined structure.

I hope for pointers on how to improve my current strategy ...

+5
source share
4 answers

Marshal's interaction classes and methods (namely PtrToStruct and StructToPtr) can also help here. See: http://msdn.microsoft.com/en-us/library/4ca6d5z7.aspx

+2
source

Rozon, I had the same problem, and I was going to refuse the solution until I found this question here and read Joe's answer to it. Joe mentions a marshal object to move data between regular MEMORY and a managed object ... Here's what I did and what worked for me as magic ... If you still don't understand what I did and how I got it to work. (Thanks, Joe!) ...

First, you should be able to create a managed instance of your structure. It should not be too complicated, it just means a lot of additional attributes in your structure.

, , . , , SURE ARE!

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
struct TServerInformation {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
    public string ComputerName;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
    public string HostName;

    [MarshalAs(UnmanagedType.U4)]
    public Int32 IPAddress;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
    public string AdminName;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
    public string WindowsDir;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
    public string Domain;
};

, CERTAIN , , Unicode, , Charset .

, ...

, ( , ), :

byte[] buff = new byte[Marshal.SizeOf(pStruct)];

, , , (, , , ...), . , , , . , [], - :

pStruct = (TServerInformation)buff.FromMemory();

- , . , try/catch/finally ...

// Create our Managed Object...
TServerInformation pStruct = new TServerInformation();
// Allocate our block of unmanaged memory...
IntPtr pMem = Marshal.AllocHGlobal(Marshal.SizeOf(pStruct));
// Copy our buff buffer into that new block of memory...
Marshal.Copy(buff, 0, pMem, buff.Length);
// Type-cast that block of memory with the results of the Marshal object help...
pStruct = (TServerInformation)Marshal.PtrToStructure(pMem, pStruct.GetType());
// Free that block of memory, that is no longer needed now that the data exists in managed form.
Marshal.FreeHGlobal(pMem);

! , , , , , "sizeof()" . , , , , 5 , , , , ...:)

, ... , .

+5

- MemoryStream , BinaryReader. ..

, endianness . EndianBinaryReader MiscUtil, , .

+4

, :

  //set your byte data instead of null
        byte[] data = null;

        MemoryStream stream = new MemoryStream();
        stream.Write(data,0,data.Length);

        BinaryFormatter formatter = new BinaryFormatter();

        Type s1 = (Type)formatter.Deserialize(stream);
0

All Articles