提交 ed74f971 编写于 作者: G Gonzalo Paniagua Javier

Fix Marshal.SizeOf() for structs with explicit layout

	Marshal.SizeOf is now returning the expected values for explicit layout
	in 32 and 64 bits systems.

	Fixes bug #641535.
上级 ad115a8a
......@@ -10614,7 +10614,7 @@ MonoMarshalType *
mono_marshal_load_type_info (MonoClass* klass)
{
int j, count = 0;
guint32 native_size = 0, min_align = 1;
guint32 native_size = 0, min_align = 1, packing;
MonoMarshalType *info;
MonoClassField* field;
gpointer iter;
......@@ -10671,6 +10671,7 @@ mono_marshal_load_type_info (MonoClass* klass)
info->native_size = parent_size;
}
packing = klass->packing_size ? klass->packing_size : 8;
iter = NULL;
j = 0;
while ((field = mono_class_get_fields (klass, &iter))) {
......@@ -10709,8 +10710,7 @@ mono_marshal_load_type_info (MonoClass* klass)
case TYPE_ATTRIBUTE_EXPLICIT_LAYOUT:
size = mono_marshal_type_size (field->type, info->fields [j].mspec,
&align, TRUE, klass->unicode);
align = klass->packing_size ? MIN (klass->packing_size, align): align;
min_align = MAX (align, min_align);
min_align = packing;
info->fields [j].offset = field->offset - sizeof (MonoObject);
info->native_size = MAX (info->native_size, info->fields [j].offset + size);
break;
......@@ -10718,8 +10718,15 @@ mono_marshal_load_type_info (MonoClass* klass)
j++;
}
if(layout != TYPE_ATTRIBUTE_AUTO_LAYOUT) {
if (layout != TYPE_ATTRIBUTE_AUTO_LAYOUT) {
info->native_size = MAX (native_size, info->native_size);
/*
* If the provided Size is equal or larger than the calculated size, and there
* was no Pack attribute, we set min_align to 1 to avoid native_size being increased
*/
if (layout == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT)
if (native_size && native_size == info->native_size && klass->packing_size == 0)
min_align = 1;
}
if (info->native_size & (min_align - 1)) {
......
......@@ -51,6 +51,50 @@ public class Test
object itf;
}
// Size should be 12 in both 32 and 64 bits
[StructLayout (LayoutKind.Explicit)]
struct TestStruct8 {
[FieldOffset (0)]
public int a;
[FieldOffset (4)]
public ulong b;
}
// Size should be 12 in both 32 and 64 bits
[StructLayout (LayoutKind.Explicit, Size=12)]
struct TestStruct9 {
[FieldOffset (0)]
public int a;
[FieldOffset (4)]
public ulong b;
}
// Size should be 11 in both 32 and 64 bits
[StructLayout (LayoutKind.Explicit)]
struct TestStruct10 {
[FieldOffset (0)]
public int a;
[FieldOffset (3)]
public ulong b;
}
// Size should be 11 in both 32 and 64 bits
[StructLayout (LayoutKind.Explicit, Size=11)]
struct TestStruct11 {
[FieldOffset (0)]
public int a;
[FieldOffset (3)]
public ulong b;
}
[StructLayout (LayoutKind.Explicit, Pack=1)]
struct TestStruct12 {
[FieldOffset (0)]
public short a;
[FieldOffset (2)]
public int b;
}
public unsafe static int Main ()
{
///
......@@ -137,7 +181,16 @@ public class Test
// a VARIANT is
if (Marshal.SizeOf (typeof (TestStruct7)) != 16)
return 13;
if (Marshal.SizeOf (typeof (TestStruct8)) != 16)
return 14;
if (Marshal.SizeOf (typeof (TestStruct9)) != 12)
return 15;
if (Marshal.SizeOf (typeof (TestStruct10)) != 16)
return 16;
if (Marshal.SizeOf (typeof (TestStruct11)) != 11)
return 17;
if (Marshal.SizeOf (typeof (TestStruct12)) != 6)
return 18;
return 0;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册