struct size?

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
 
W

Wim Hollebrandse

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
 
W

William Stacey

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!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top