struct size?

  • Thread starter Thread starter Dirk Reske
  • Start date Start date
D

Dirk Reske

Hello,

I have the following struct:

public struct WAVEFORMATEX
{
public UInt16 wFormatTag; //2 bytes
public UInt16 nChannels; //2 bytes
public UInt32 nSamplesPerSec; //4 bytes
public UInt32 nAvgBytesPerSec; //4 bytes
public UInt16 nBlockAlign; //2 bytes
public UInt16 wBitsPerSample; //2 bytes
public UInt16 cbSize; //2 bytes
}

why returns Marshal.SizeOf(typeof(WAVEFORMATEX)) 20??
the size of this struct is only 18 bytes
 
This has to do the alignment overhead of the member fields of your structs.

This overhead equals the largest field in your struct, which is 4 bytes. The total size of your struct will have to be 4 bytes chunks, and 18 div 4 leaves 2. Hence the extra 2 bytes - 5 blocks of 4 bytes.

If you get did get rid of one of the short member fields, you'd notice the structsize would be 16.

Hope that helps.

Wim Hollebrandse
http://www.wimdows.net
http://www.wimdows.com
 
I assume you need get your struct into a byte[] and back. If so, here are two options without using the BitConverter and iterating over all your members seperately:

MyStruct1 myStruct1;
myStruct1.myshort = 12;
myStruct1.mylong = 3035;
int size;
byte[] ba;
IntPtr ips;
IntPtr ips2;
//Could use unsafe keyword on the method, but do this way to show where it is needed.
unsafe
{
size = sizeof(MyStruct1);
ba = new byte[size];
byte * pStruct = (byte*)&myStruct1.myshort; //Get a pointer to the first byte.
byte * pStruct2 = (byte*)&myStruct1; //Do they point to same place?
ips = (IntPtr)pStruct; //Cast to an IntPtr for the Marshal.Copy
ips2 = (IntPtr)pStruct2; //method and to see the address.
}
Console.WriteLine("Option1: Copy a Struct to byte[] using Marshal.Copy and back.");
Console.WriteLine("Pointer bp is:"+ ips);
Console.WriteLine("Pointer bp2 is:"+ ips2); //Same as ips? yes.
Marshal.Copy((IntPtr)ips, ba, 0, size); //Copy struct to byte[].

//Now copy byte array back to a new struct and see if same.
MyStruct1 myNewStruct;
myNewStruct.myshort = 0; //Set zero to prove we changed
myNewStruct.mylong = 0; //and to avoid "unassigned" compiler warning.
IntPtr ip;
unsafe
{
ip = (IntPtr)(byte*)&myNewStruct.myshort;
}
Marshal.Copy(ba, 0, ip, size);
Console.WriteLine("Created a new struct and copied bytes to it.");
Console.WriteLine("myNewStruct.myshort:"+myNewStruct.myshort +
" myNewStruct.mylong:"+myNewStruct.mylong);
Console.WriteLine();

//
//Option#2 - Use Marshal.PtrToStructure and StructureToPtr.
//
ba = new byte[size];
MyStruct1 struct1;
struct1.myshort = 88;
struct1.mylong = 40877;
unsafe
{
//Need fixed in this option because we need a pointer to the managed byte[].
fixed ( byte * fixed_buf = ba )
{
ip = (IntPtr)fixed_buf;
}
}
Marshal.StructureToPtr(struct1, ip, true);
MyStruct1 newStruct = (MyStruct1)Marshal.PtrToStructure(ip, typeof(MyStruct1));
Console.WriteLine("Option2: Copy a struct to byte[] using Marshal.StructureToPtr");
Console.WriteLine("newStruct.myshort:"+newStruct.myshort+" newStruct.mylong:"+newStruct.mylong);
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct MyStruct1
{
public short myshort;
public long mylong;
}

HTH!
 
Back
Top