When passing a managed byte[] array through PInvoke to be filled in by Win32, does it need to be pinned?

Short Answer: No, pinning is not necessary in this case

Longer Answer:

The CLR will automatically pin references to managed objects when they cross the PInvoke boundary. As soon as the PInvoke function exits the reference will be unpinned. So in situations like having a native function fill a byte[] no manually pinning is necessary because the object is only used by native code during the function call.

Manually pinning of the array becomes necessary if the native code caches the managed pointer. When this happens you must manually pin the array until the native code no longer needs the pointer. In this case I presume the pointer is not cached hence it's not necessary to pin

Reference - http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2


according to msdn Marshaling Arrays of Types only an array passed by reference can be written to by unmanaged code. So it appears that you must declare the array parameter [out] or [in,out] if you want to fill it in on the unmanaged side.

This page http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspx manages to go on and on without ever explicitly saying that the marshaller pins the arrays during the call from managed to unmanaged, but much of what it describes wouldn't work if the marshaller didn't pin.