As strange as it sounds, modern programming languages have many different representations for strings. In C#, a string is represented by a 32-bit integer that stores the number of characters in the string, followed by an array of two-byte UTF16-encoded characters. Unity’s core::string in C++ uses a machine-sized integer for the number characters, but stores those characters in an array of one-byte, UTF8-encoded values.

These different representations mean strings are not blittable, so we need to do some marshaling to get the data back and forth across this managed/native boundary. This marshaling involves allocation of a properly sized buffer of data and conversion of the character information, ensuring that values from all possible locales work properly.

Normally, C# developers can ask the .NET runtime to handle these details, using its built-in p/invoke marshaling. Unity, though, has a custom marshaling tool that we call the bindings generator.

Source: Unity Technologies Blog