I've defined a struct to send via socket. I'd like to get the size of it but sizeof is unsafe and the same for "System.Runtime.InteropServices.MarshalSizeOf". Is there a way to get its size in a safe way?
2 Answers
There is no way to do it for managed structs. Marshal.SizeOf will only return the size of the data on the marshaled types that comprise the struct... that MIGHT be correct for the managed types on some platforms, but not on others.
This is by design so the JIT can lay structs differently depending on the platform it runs on.
More info here: Chris Brumme's blog
7 Comments
sizeof) or it's for a P/Invoke (in which case Marshal.SizeOf is the correct answer).sizeof then, but that's unsafe (as per definition of unsafe by the JIT, i.e., outside its memory-checking limits) if you want to write directly to a memory page or unserialized (direct from memory) data to a file... there's no problem using sizeof (or unsafe blocks, or pointers, or pinning), but you are stepping outside the "correctnes" and memory safety that the CLR provides on its "safe" blocksSee my blog post for a wrapper library that lets you determine what the JIT will define the managed type's size will be(at runtime). It works by using the sizeof IL instruction which isn't exposed at all in C#. It can be run with no special permissions at all and is verifiable.
Note: this may or may not be what you actually want. This might return 8 for a structure that actually only has a single byte in it. I don't really understand your question completely, so I'm not sure if this is actually what you want or not.
Marshal.SizeOfis perfectly safe as far as the CLR is concerned.Marshal.SizeOfwill fail if the struct is a generic type. See informit.com/guides/content.aspx?g=dotnet&seqNum=728 for info and one way to get around the problem.