Reputation: 1700
Well, there are some obvious differences:
fixed buffer:
-unsafe
switch).using MarshalAs
attribute:
But what I cannot find answer for, is why fixed buffer are needed in the first place?
When one must use them?
Why one would want to use it, assuming one can validate the size of regular managed array?
I can think of performance constraints, that might make one choose fixed buffer over regular arrays...
Is that all?
Thanks in advance.
Upvotes: 5
Views: 550
Reputation: 942040
Yes, efficiency is certainly the primary reason. When you apply UnmanagedType.ByValArray
then the struct must always be marshaled. In other words, the CLR is forced to create a new copy of the struct and initialize it with the values from the managed struct since the unmanaged layout of the struct is different. That can be avoided when you use a fixed buffer, provided the other members of the struct are blittable as well. In which case the CLR can simply pass a pointer to the struct. Much faster of course.
There are a few interop scenarios where you must use a fixed size buffer. Typically when the array member is misaligned, that violates the atomicity guarantee of the .NET memory model. Or you declare a union (fields overlap each other) and the CLR objects against overlapping a field of a reference type with a field of a value type. That's incompatible with the garbage collector, it cannot reliably detect the object pointer. You'll get a TypeLoadException at runtime when that's the case.
Both scenarios are fundamentally unverifiable. It is always unsafe if the native code writes back to the struct, memory corruption occurs when it writes past the end of the array. Extremely hard to diagnose. The need to explicitly use the unsafe keyword when you use a fixed size buffer only applies to the lack of index checking when you access the fixed size buffer in your C# code.
Upvotes: 6