Search code examples
c#performanceintptr

Minimizing overhead in IntPtr to String conversion


I have an IntPtr (representing a char*) received from a C++ DLL, and I want to convert it to a string in C#. Is Span<char>.ToString always generating a new string instance, or is there a way to avoid creating a new string when converting from IntPtr? Any advice would be greatly appreciated!

Additionally, the resulting string will be bound to a property in WinUI 3 XAML.

// Simulate a char* received from C++
String original = "Hello";
IntPtr ptr = Marshal.StringToHGlobalUni(original); // Allocate as UTF-16 (char*)

try
{
    // Convert IntPtr to Span<char> and then to String
    Span<char> span = new Span<char>(ptr.ToPointer(), original.Length);
    String result = span.ToString();
}
finally
{
    Marshal.FreeHGlobal(ptr);
}

Solution

  • If your C++ code is generating lots of duplicate strings, you could string.Intern() them to save memory. But I don't think that's what you're asking about.

    Creating a string from any kind of memory buffer will require a copy of that string to be allocated. Using a Span<char> to help track the memory buffer shouldn't add any overhead, since a span can only exist on the stack and only really contains a pointer and length.

    Since string is supposed to be immutable, the runtime must guarantee that the memory buffer can't be manipulated by some rogue C++ code that kept a copy of the memory address. While you can break that rule with unsafe code, I wouldn't recommend it.

    If the memory allocation is causing a significant performance issue, then perhaps you should avoid using string at all.