Marshal.SizeOf throws an ArgumentException on enumerations

Consider this code:

public enum MyEnum { V1, V2, V3 } int size = Marshal.SizeOf(typeof(MyEnum)); 

it throws an exception:

An unhandled exception of type "System.ArgumentException" occurred in TestConsole.exe

Additional information: Type 'TestConsole.Program + MyEnum' cannot be marshaled as an unmanaged structure; no significant size or offset calculated.

So far, this code does not throw an exception, and size contains 4:

 public enum MyEnum { V1, V2, V3 } public struct MyStruct { public MyEnum en; } int size = Marshal.SizeOf(typeof(MyStruct)); 

Can someone explain why the .NET Framework cannot figure out that enum is 4 bytes in the first code sample?

UPDATE

Marshal.Sizeof() failed for me in this general method:

 public bool IoControlReadExact<T>(uint ioControlCode, out T output) where T : struct { output = new T(); int outBufferSize = Marshal.SizeOf(typeof(T)); IntPtr outBuffer = Marshal.AllocHGlobal(outBufferSize); if (outBuffer == IntPtr.Zero) return false; try { uint bytesReturned; return IoControlRead(ioControlCode, outBuffer, (uint)outBufferSize, out bytesReturned) && ((uint)outBufferSize == bytesReturned); } finally { output = (T)Marshal.PtrToStructure(outBuffer, typeof(T)); Marshal.FreeHGlobal(outBuffer); } } 

And the compiler did not complain about enum not struct .

Decision

I could reorganize my general method so that it works for both struct and enum :

 // determine the correct output type: Type outputType = typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T); //... int outBufferSize = Marshal.SizeOf(outputType); //... output = (T)Marshal.PtrToStructure(outBuffer, outputType); 
+43
enums c # marshalling
Jul 26 '13 at 11:09 on
source share
2 answers

This is apparently the restriction imposed by the difference between the requirements of ECMA-335 for enumerations (ECMA-335 Partition II, section 14.3):

... they must have a layout of the automatic field (ยง10.1.2); ...

And the expectations of Marshal.SizeOf :

You can use this method if you do not have a structure. Layout must be consistent or explicit.

Based on this, you will need to use Enum.GetUnderlyingType before calling Marshal.SizeOf .

+25
Jul 26 '13 at 12:34 on
source share
โ€” -

Marshal.SizeOf(t) wants to have an unmanaged structure, and enum wants a managed structure. .NET can define a constant enumeration size:

 int size1 = sizeof(MyEnum); Console.WriteLine("Enum: {0}", size1); int size2 = Marshal.SizeOf(typeof(MyStruct)); Console.WriteLine("Struct: {0}", size2); 
0
Jul 26 '13 at 11:35
source share



All Articles