문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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;
}

According to this article: http://support.microsoft.com/kb/311259 PtrToStringChars is officially supported and may be used. It is described as "get an interior gc pointer to the first character contained in a System::String object" in vcclr.h .

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top