- 
        Couldn't load subscription status. 
- Fork 5.2k
Description
There are a few places in the docs that seem to state inconsistent/contradictory facts on how StringBuilder is treated during PInvoke marshaling. Please clarify which is correct, and adjust the docs as appropriate to reduce future confusion.
Some docs state that when a StringBuilder is passed by value to PInvoke, a pointer to the internal buffer is passed to native, and no copy occurs. E.g.:
- Docs >.NET > .NET Framework > Interoperate with unmanaged code > Copying and Pinning:
 sub-section "System.String and System.Text.StringBuilder":
When a System.Text.StringBuilder is passed by value, the marshaler passes a reference to the internal buffer of the StringBuilder directly to the caller. The caller and callee must agree on the size of the buffer. The caller is responsible for creating a StringBuilder of adequate length. The callee must take the necessary precautions to ensure that the buffer is not overrun. StringBuilder is an exception to the rule that reference types passed by value are passed as In parameters by default. It is always passed as In/Out.
- Docs > .NET > .NET Framework > Interoperate with unmanaged code > Default Marshaling for Strings
 sub-section "Fixed-Length String Buffers":
[...] The solution is to pass a StringBuilder buffer as the argument instead of a String. A StringBuilder can be dereferenced and modified by the callee, provided it does not exceed the capacity of the StringBuilder. It can also be initialized to a fixed length. [...]
Conversely, other docs explicitly recommend avoiding the use of StringBuilder stating that a copy of the internal buffer always occurs. E.g.:
- Docs > .NET > .NET fundamentals > Native interoperability best practices
 sub-section "String parameters":
AVOID StringBuilder parameters. StringBuilder marshaling always creates a native buffer copy. [...]
- Docs > .NET > .NET fundamentals > CA1838: Avoid StringBuilder parameters for P/Invokes
 entire page:
Marshaling of StringBuilder always creates a native buffer copy, resulting in multiple allocations for one P/Invoke call. To marshal a StringBuilder as a P/Invoke parameter, the runtime will:
- Allocate a native buffer.
- If it is an In parameter, copy the contents of the StringBuilder to the native buffer.
- If it is an Out parameter, copy the native buffer into a newly allocated managed array.
[...]