
System.String and System.Text.StringBuilder
When data is marshaled to unmanaged code by value or by reference, the marshaler typically copies the data to a secondary buffer (possibly converting character sets during the copy) and passes a reference to the buffer to the callee. Unless the reference is a BSTR allocated with SysAllocString, the reference is always allocated with CoTaskMemAlloc.
As an optimization when either string type is marshaled by value (such as a Unicode character string), the marshaler passes the callee a direct pointer to managed strings in the internal Unicode buffer instead of copying it to a new buffer.
Caution: |
|---|
When a string is passed by value, the callee must never alter the reference passed by the marshaler. Doing so can corrupt the managed heap.
|
When a System..::.String is passed by reference, the marshaler copies the contents the string to a secondary buffer before making the call. It then copies the contents of the buffer into a new string on return from the call. This technique ensures that the immutable managed string remains unaltered.
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.