The following code works, but I can't figure out why. I take a struct with
two members, a single byte and byte[]. I then marshal the whole struct to a
byte[]. I create a new struct (without init'ing any members) and marshal
the tmp array back to the new struct. The new struct shows the same data.
The single type is easy, that just gets copied. The byte[] ref type is the
interesting part. The address (i.e ref) of the original byte[] gets copied
to the new struct - unless marshal is changing this. But swba.ba[0] and
newswba.ba[0] point to different places. How is Marshal.PtrToStructure
picking up the byte[] values based on a pointer it gets from the byte[]?
public unsafe static void StructTest()
{
StructWithByteArray swba = new StructWithByteArray();
swba.b = 77; swba.ba = new byte[]{12, 24}; //Set some data.
byte[] tmpBA = new byte[Marshal.SizeOf(swba.GetType())];
fixed(byte * swbaPtr = &swba.ba[0]) //Get address to swba.ba[0];
{
fixed(byte * p = &tmpBA[0])
{
//Copy struct to tmpBA byte[].
Marshal.StructureToPtr(swba, (IntPtr)p, true);
//Print address swba.ba points to.
byte * tmpP = p;
tmpP++; //Move pointer one byte.
uint addOfArray = (uint)Marshal.ReadIntPtr((IntPtr)tmpP);
Console.WriteLine("Address that swba.ba points to:"+addOfArray);
Console.WriteLine("Address that swba.ba[0] points to:"+(uint)swbaPtr);
swba.b = 0; swba.ba = null; //empty to show we get new values from
byte[].
//Copy tmpBA byte[] to a new struct.
StructWithByteArray newswba; //declare a new struct.
newswba = (StructWithByteArray)Marshal.PtrToStructure((IntPt r)p,
swba.GetType());
//Print address (ptr) of first byte in new array.
fixed(byte * pp = &newswba.ba[0])
{
Console.WriteLine("Address that newswba.ba[0] points to:"+(uint)pp);
}
Console.WriteLine("newswba.b:"+newswba.b);
Console.WriteLine("newswba.ba[0] and
[1]:"+newswba.ba[0]+","+newswba.ba[1]);
}
}
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
public unsafe struct StructWithByteArray
{
public byte b; // 1 byte.
public byte[] ba; // 4 bytes. Total 5.
}
Output:
StructToArray Size:5
Address that swba.ba points to:1710008
Address that swba.ba[0] points to:78244152
Address that newswba.ba[0] points to:78244884
newswba.b:77
newswba.ba[0] and [1]:12,24
--
William Stacey, MVP