views:

87

answers:

3

Hi, This is related to my previous question, and thought will make this as a sparate question as it will make more sense.

I have created my Struct as :

public struct Smb_Parameters
        {
            public byte WordCount;
            public ushort[] Words;
        }

Without Assigning any Values when I try to get the size of the Struct it returns 4-Bytes:

Smb_Parameters smbParameter = new Smb_Parameters();
int len1 = Marshal.SizeOf(smbParameter );
            MessageBox.Show(len1.ToString());

But When I assign the Values to structure fields :

 Smb_Parameters smbParameter = new Smb_Parameters();
 string myString= "String  ll be converted to byte";
 smbParameter.WordCount=0x00;
 smbParameter .Words=Encoding.ASCII.GetBytes(myString);
 int len1 = Marshal.SizeOf(smbParameter );
 MessageBox.Show(len1.ToString());

Still now It shows the Length as 4-Bytes but I need the updated size.

+1  A: 

The Words field is an array, and arrays are reference types. The structure doesn't actually contains the array items, it only contains a reference to the array, which is stored somewhere else (typically on the heap). So SizeOf always returns the same size, since the size of a reference doesn't depend on the size of the object pointed by that reference.

Thomas Levesque
@Thomas Levesque, Thanks. Is there a way we can get the actual size of the strucure.
Subhen
The actual size of the structure is exactly what is returned by Marshal.SizeOf... it's just that the array items are NOT part of the structure
Thomas Levesque
+2  A: 

If you wish to get the size as if it was an unmanaged type, you'd need to supply some information about its fields (e.g., the length of the array). Without it, the array length would not be taken into account.

e.g.,

public struct Smb_Parameters1
{
    public byte WordCount; //1 byte
    public ushort[] Words; //4 bytes (a "pointer")
}
Marshal.SizeOf(typeof(Smb_Parameters1)); //8 (with padding)
//I don't see how you get 4 unless you are on a 16-bit system maybe

[StructLayout(LayoutKind.Sequential)]
public struct Smb_Parameters2
{
    public byte WordCount; //1 byte
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=10)]
    public ushort[] Words; //20 bytes (2 * 10 bytes)
}
Marshal.SizeOf(typeof(Smb_Parameters2)); //22 (with padding)

Note that these are sizes are fixed (as if it was declared in a C/C++ program). The size reported by SizeOf() will only use these and not take into account what size array you store in Words.

Smb_Parameters1 s1 = new Smb_Parameters1() { Words = new ushort[] { 0, 1, 2 } };
Smb_Parameters2 s2 = new Smb_Parameters2() { Words = new ushort[] { 0, 1, 2 } };
Marshal.SizeOf(s1); //8 bytes
Marshal.SizeOf(s2); //22 bytes
Jeff M
May be I am getting 4 because I am using Marshal.SizeOf(Smb_Parameters1); not Marshal.SizeOf(typeof(Smb_Parameters1)); I am quite sure though it is not a 16-bit System
Subhen
A: 

Marshal.SizeOf() returns a fixed size of an class/struct. The length does never depend on the contents of your object passed.

You could calculate the size with Marshal.SizeOf(typeof(byte))+Marshal.SizeOf(typeof(ushort))*yourarraylength

Another way would be to use the BinaryFormatter class to serialize your struct into binary form. It returns you a byte array. If you take the length of it you know its serialized size. Note that the result of BinaryFormatter cannot not be easily read by a non-.net language since its format is native to .net only.

codymanix