4

The goal is to avoid copying the string data when I need a const wchar_t*.

The answer seems to be yes, but the function PtrToStringChars doesn't have its own MSDN entry (it's only mentioned in the KB and blogs as a trick). That made me suspicious and I want to check with you guys. Is it safe to use that function?

Community
  • 1
  • 1
CannibalSmith
  • 4,742
  • 10
  • 44
  • 52

2 Answers2

4

Here is a complete solution based on PtrToStringChars that accesses the managed string internals and then copies the contents using standard C functions:

wchar_t *ManagedStringToUnicodeString(String ^s)
{
    // Declare
    wchar_t *ReturnString = nullptr;
    long len = s->Length;

    // Check length
    if(len == 0) return nullptr;

    // Pin the string
    pin_ptr<const wchar_t> PinnedString = PtrToStringChars(s);

    // Copy to new string
    ReturnString = (wchar_t *)malloc((len+1)*sizeof(wchar_t));
    if(ReturnString)
    {
        wcsncpy(ReturnString, (wchar_t *)PinnedString, len+1);
    }

    // Unpin
    PinnedString = nullptr;

    // Return
    return ReturnString;
}
Theo
  • 5,963
  • 3
  • 38
  • 56
2

Yes, no problem. It is actually somewhat documented but hard to find. The MSDN docs for the C++ libraries aren't great. It returns an interior pointer, that's not suitable for conversion to a const wchar_t* yet. You have to pin the pointer so the garbage collector cannot move the string. Use pin_ptr<> to do that.

You can use Marshal::StringToHGlobalUni() to create a copy of the string. Use that instead if the wchar_t* needs to stay valid for an extended period of time. Pinning objects too long isn't very healthy for the garbage collector.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 2
    I wouldn't recommend `StringToHGlobalUni`. Using `PtrToStringChars` and then making a copy yourself could be quite a bit faster than messing with HGLOBAL, which is a specialized allocator with limited practical use. Actually `marshal_as` or `marshal_as` would be by recommendations for a native copy. http://msdn.microsoft.com/en-us/library/bb384865.aspx – Ben Voigt Jun 21 '10 at 03:16