17.4 In and Out Marshaling

The previous Test example works if SystemTime is a struct and t is a ref parameter, but is actually less efficient:

struct SystemTime {...}
static extern void GetSystemTime(ref SystemTime t);

This is because the marshaler must always create fresh values for external parameters, so the previous method copies t when going in to the function. It then copies the marshaled t when coming out of the function. By default, pass-by-value parameters are copied in, C# ref parameters are copied in/out, and C# out parameters are copied out, but there are exceptions for the types that have custom conversions. For instance, array classes and the StringBuilder class require copying when coming out of a function, so they are in/out. It is occasionally useful to override this behavior, with the In and Out attributes. For example, if an array should be read-only, the in modifier indicates to only copy the array going into the function, and not come out of it:

static extern void Foo([In] int[ ] array);

    Part II: Programming with the .NET Framework
    Part IV: API Quick Reference