Given a struct MyStruct, I can get the size of instances of that struct using sizeof(MyStruct) in unsafe code. However, I want to get the size of a struct given the Type object for the struct, ie, sizeof(typeof(MyStruct)). There is Marshal.SizeOf, but that returns the unmanaged marshalled size, whereas I want the managed size of that struct.
- Would a profiler meet your needs?ChaosPandion– ChaosPandion2010-12-17 16:22:21 +00:00Commented Dec 17, 2010 at 16:22
- 1Not sure if anyone can answer this but why would the managed struct be a different size to the unmanaged one? Both are the same C# struct.Lazarus– Lazarus2010-12-17 16:24:11 +00:00Commented Dec 17, 2010 at 16:24
- @ChaosPandion: I need to get the size of an arbitary struct at runtimethecoop– thecoop2010-12-17 16:24:18 +00:00Commented Dec 17, 2010 at 16:24
- 1Have a look at stackoverflow.com/questions/2127707 In short: there is a internal overload of Marshal.SizeOf that returns the managed size of a struct.dtb– dtb2010-12-17 16:31:41 +00:00Commented Dec 17, 2010 at 16:31
- 1@Lazarus: The marshaller applies several transformations to a struct before passing it to a native method via P/Invoke. The layout of structs in managed memory is different.dtb– dtb2010-12-17 16:32:44 +00:00Commented Dec 17, 2010 at 16:32
| Show 1 more comment
1 Answer
There is no documented way to discover the layout of a managed struct. The JIT compiler takes readily advantage of this, it will reorder fields of the struct to get the best packing. Marshaling is always required to get a predictable layout, as directed by the [StructLayout] attribute. You have to jump through the Marshal.StructureToPtr() hoop. Whether you do it yourself or let the pinvoke marshaller do it for you.
Marshal.SizeOf(Type) gives you the size of the marshaled struct. More background on why it works this way is available in this answer.
9 Comments
dtb
If I'm not mistaken, the StructLayout attribute actually does affect how the CLR lays out the struct in managed memory. Only with LayoutKind.Auto the CLR is free to lay out the struct as it sees fit. Wih LayoutKind.Sequential (the default in C#) and LayoutKind.Explicit it's possible to get predictable layouts.
Hans Passant
This is accurate. A struct type has a default [StructLayout] if you don't apply one yourself. Unlike a class.
dtb
Sou couldn't one use reflection to determine the layout for a struct with LayoutKind.Sequential or LayoutKind.Explicit and calculate its size this way?
Hans Passant
@dtb - Type.StructLayoutAttribute.Kind is still Sequential, regardless of whether it was auto-generated or not. Reflection doesn't provide the actual internal layout, only the marshaled layout.
dtb
Reflection doesn't provide any layout at all. It just tells you the fields of the struct and its attributes. The StructLayout attributes affects the layout of the struct in managed memory. With LayoutKind.Sequential (auto-generated or explicitly declared) and LayoutKind.Explicit (when explicitly declared) you can create a predictable struct layout in managed memory. Since the layout is determined by the StructLayout/FieldOffset attributes, which are discoverable using reflection, it should be possible to calculate the layout and thereby its size.
|