Blimey! almost 3 years and there is no right answer to this question yet!
The right way to pass strings from an unmanaged one is to, at least in my experience, combine the StringBuilder class with an extra parameter representing the size of the "buffer".
Something like that:
// C# [DllImport("MyLib.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern bool MyFunction( // other parameters, StringBuilder buffer, [MarshalAs(UnmanagedType.U4)] int bufferSize ); // C: extern "C" __declspec(dllexport) BOOL MyFunction(bunch of params, LPTSTR* text, unsigned int textSize) { //lots of code if ( textSize < requiredSize) { SetLastError(ERROR_INSUFFICIENT_BUFFER) return FALSE; } return TRUE; }
And use it like this:
StringBuilder sb = new StringBuilder(128); while (!NativeMethods.MyFunction(, sb, sb.Capacity)) { if (Marshal.GetLastWin32Error() != 0x7A) {
source share