What I've found to work best is to be more explicit about what's going on here. Having a string as return type is probably not recommended in this situation.
A common approach is to have the C++ side be passed the buffer and buffer size. If it's not big enough for what GetString has to put in it, the bufferSize variable is modified to indicate what an appropriate size would be. The calling program (C#) would then increase the size of the buffer to the appropriate size.
If this is your exported dll function (C++):
extern "C" __declspec void GetString( char* buffer, int* bufferSize );
Matching C# would be the following:
void GetString( StringBuilder buffer, ref int bufferSize );
So to use this in C# you would then do something like the following:
int bufferSize = 512;
StringBuilder buffer = new StringBuilder( bufferSize );
GetString( buffer, ref bufferSize );
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…