Convert parts of byte[] to struct

  • Thread starter Thread starter Amil Hanish
  • Start date Start date
A

Amil Hanish

I have a huge byte array from another API that contains structs of differing
sizes. I'd like to create n structs based on data in the byte array. But
how? For example, if I want to take bytes 40-56 and create struct Foo from
them...how do I do this? You can assume I know how to create the properly
aligned struct.

Thanks

Amil
 
You should use unsafe in combination with fixed in the following manner:
STRUCT strct;
byte[] MyArray = new byte[100];
unsafe
{
fixed(byte *pPtr = &MyArray[0])
{
STRUCT *ps = &strct;
*ps = *(STRUCT*)(pPtr + 53);
}
}

Note that your struct MUST include only value types so the memory layout
will directly represent the struct variables.
 
AND you should use:
[ StructLayout( LayoutKind.Sequential )]


Nadav said:
You should use unsafe in combination with fixed in the following manner:
STRUCT strct;
byte[] MyArray = new byte[100];
unsafe
{
fixed(byte *pPtr = &MyArray[0])
{
STRUCT *ps = &strct;
*ps = *(STRUCT*)(pPtr + 53);
}
}

Note that your struct MUST include only value types so the memory layout
will directly represent the struct variables.



Amil Hanish said:
I have a huge byte array from another API that contains structs of
differing
sizes. I'd like to create n structs based on data in the byte array.
But
how? For example, if I want to take bytes 40-56 and create struct Foo
from
them...how do I do this? You can assume I know how to create the
properly
aligned struct.

Thanks

Amil
 
You may utilize the features of System.Runtime.InteropServices.Marshal:

byte [] buff = new byte [Marshal.SizeOf(typeof(MYSTRUCT))];
/* Put data into buffer here. */
IntPtr ptr = Marshal.AllocHGlobal(buff.Length);
Marshal.Copy(buff, 0x0, ptr, buff.Length);
MYSTRUCT myStruct = (MYSTRUCT) Marshal.PtrToStructure(ptr,
typeof(MYSTRUCT));
Marshal.FreeHGlobal(ptr);


If you are OK with using "unsafe" code, i think this is the superior version
(you will have to compile with the /unsafe switch):

MYSTRUCT myStruct;
byte [] buff = new byte [sizeof(MYSTRUCT)];
/* Put data into buffer here. */
unsafe
{
fixed (byte * pBuff = buff)
myStruct = * ((MYSTRUCT *) pBuff);
}


Remember to explicitly specify that the members of the struct must not
be organized in another way than in the order that they are defined.
This is done with the System.Runtime.InteropServices.StructLayoutAttribute
attribute:

[ StructLayout( LayoutKind.Sequential, Pack = 0x1 ) ]
struct MYSTRUCT
{
....
}
 
Just a little modification:
MYSTRUCT myStruct;
byte [] buff = new byte [sizeof(MYSTRUCT)];
/* Put data into buffer here. */
unsafe
{
fixed (byte * pBuff = buff)
myStruct = * ((MYSTRUCT *) pBuff);
}

should be:

MYSTRUCT myStruct;
unsafe
{
byte [] buff = new byte [sizeof(MYSTRUCT)];
/* Put data into buffer here. */
fixed (byte * pBuff = buff)
myStruct = * ((MYSTRUCT *) pBuff);
}


--
Regards,
Dennis JD Myrén
Oslo Kodebureau
Dennis Myrén said:
You may utilize the features of System.Runtime.InteropServices.Marshal:

byte [] buff = new byte [Marshal.SizeOf(typeof(MYSTRUCT))];
/* Put data into buffer here. */
IntPtr ptr = Marshal.AllocHGlobal(buff.Length);
Marshal.Copy(buff, 0x0, ptr, buff.Length);
MYSTRUCT myStruct = (MYSTRUCT) Marshal.PtrToStructure(ptr,
typeof(MYSTRUCT));
Marshal.FreeHGlobal(ptr);


If you are OK with using "unsafe" code, i think this is the superior
version
(you will have to compile with the /unsafe switch):

MYSTRUCT myStruct;
byte [] buff = new byte [sizeof(MYSTRUCT)];
/* Put data into buffer here. */
unsafe
{
fixed (byte * pBuff = buff)
myStruct = * ((MYSTRUCT *) pBuff);
}


Remember to explicitly specify that the members of the struct must not
be organized in another way than in the order that they are defined.
This is done with the System.Runtime.InteropServices.StructLayoutAttribute
attribute:

[ StructLayout( LayoutKind.Sequential, Pack = 0x1 ) ]
struct MYSTRUCT
{
...
}


--
Regards,
Dennis JD Myrén
Oslo Kodebureau
Amil Hanish said:
I have a huge byte array from another API that contains structs of
differing
sizes. I'd like to create n structs based on data in the byte array.
But
how? For example, if I want to take bytes 40-56 and create struct Foo
from
them...how do I do this? You can assume I know how to create the
properly
aligned struct.

Thanks

Amil
 
Hi,

Amil Hanish said:
I have a huge byte array from another API that contains structs of
differing
sizes. I'd like to create n structs based on data in the byte array. But
how? For example, if I want to take bytes 40-56 and create struct Foo
from
them...how do I do this? You can assume I know how to create the properly
aligned struct.

Here is a (another) way to do it without unsafe code :

// yourdata
byte[] data = ....;

// pin the byte array
GCHandle hData = GCHandle.Alloc( data, GCHandleType.Pinned );

// get an address into the byte array
IntPtr pData = Marshal.UnsafeAddrOfPinnedArrayElement( data,
YourStartIdxHere );

// marshal/copy the unmanaged struct to a managed one
YourStruct ys = (YourStruct) Marshal.PtrToStruct( pData,
typeof(YourStruct) );

// free pinning
hData.Free();

// ys can be used




The length is determined by the (unmanaged) size of the struct.


HTH,
greetings
 
Back
Top