LayoutKind.Explicit & and FieldOffset not working?

B

Beorne

[StructLayout(LayoutKind.Explicit)]
unsafe struct Structure
{
[FieldOffset(0)]
public byte b;
[FieldOffset(1)]
public double d;
}

Why Marshal.SizeOf(typeof(SPESharedRecord2)) has a value of 16 instead
of 9?
Analyzing the struct I have found field d starts at byte 8 and not
byte 1, why?
 
J

Jeroen Mostert

Beorne said:
[StructLayout(LayoutKind.Explicit)]
unsafe struct Structure
{
[FieldOffset(0)]
public byte b;
[FieldOffset(1)]
public double d;
}

Why Marshal.SizeOf(typeof(SPESharedRecord2)) has a value of 16 instead
of 9?

Because the structure is padded to platform alignment, even if you
explicitly lay out the fields. To suppress this, use
StructLayout(LayoutKind.Explicit, Pack = 1) and the struct will have the
expected size.
Analyzing the struct I have found field d starts at byte 8 and not
byte 1, why?

I have no idea, because on my machine, this works as expected. I suggest you
recheck your findings. In particular, keep in mind that doubles are encoded
in a specific way, so the bytes may not have the values you expect them to.
The double really is stored in bytes 1-8, though.
 
J

Jeroen Mostert

Jeroen said:
Beorne said:
[StructLayout(LayoutKind.Explicit)]
unsafe struct Structure
{
[FieldOffset(0)]
public byte b;
[FieldOffset(1)]
public double d;
}

Why Marshal.SizeOf(typeof(SPESharedRecord2)) has a value of 16 instead
of 9?

Because the structure is padded to platform alignment, even if you
explicitly lay out the fields. To suppress this, use
StructLayout(LayoutKind.Explicit, Pack = 1) and the struct will have the
expected size.
Forgot to add that if you do use Pack = 1, you don't need to lay out the
fields either in this case. LayoutKind.Sequential will have the same effect.
 
B

Beorne

Jeroen said:
Beorne said:
[StructLayout(LayoutKind.Explicit)]
unsafe struct Structure
{
[FieldOffset(0)]
public byte b;
[FieldOffset(1)]
public double d;
}
Why Marshal.SizeOf(typeof(SPESharedRecord2)) has a value of 16 instead
of 9?
Because the structure is padded to platform alignment, even if you
explicitly lay out the fields. To suppress this, use
StructLayout(LayoutKind.Explicit, Pack = 1) and the struct will have the
expected size.

Forgot to add that if you do use Pack = 1, you don't need to lay out the
fields either in this case. LayoutKind.Sequential will have the same effect.

I'm using the Compact Framework that does not suport the Pack
attribute. Perhaps the problem is there ....
 
J

Jeroen Mostert

Beorne said:
Jeroen said:
Beorne wrote:
[StructLayout(LayoutKind.Explicit)]
unsafe struct Structure
{
[FieldOffset(0)]
public byte b;
[FieldOffset(1)]
public double d;
}
Why Marshal.SizeOf(typeof(SPESharedRecord2)) has a value of 16 instead
of 9?
Because the structure is padded to platform alignment, even if you
explicitly lay out the fields. To suppress this, use
StructLayout(LayoutKind.Explicit, Pack = 1) and the struct will have the
expected size.
Forgot to add that if you do use Pack = 1, you don't need to lay out the
fields either in this case. LayoutKind.Sequential will have the same effect.
I'm using the Compact Framework that does not suport the Pack
attribute. Perhaps the problem is there ....

Yes, and that's a rotten situation to be in. Because you can't enforce
struct packing alignment, you have to do without it.

The next question would be: what do you need this struct for? In particular,
why do you need it to be packed? If push comes to shove, you can almost
always work around this by just not using structs. (If you're using .NET CF
2.0, however, your job is considerably harder.)

If you need to convert this struct to bytes to send it over the wire or to a
file somewhere, it's always an option to just send those bytes directly with
the help of BitConverter.

If you need to pass this struct to an API, then just passing it with extra
alignment will probably work, as long as you don't use Marshal.SizeOf() and
pass the desired size explicitly.
 

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