开发者

Is it possible to get a pointer to String^'s internal array in C++/CLI?

开发者 https://www.devze.com 2023-01-03 07:53 出处:网络
The goal is to a开发者_开发技巧void 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 me

The goal is to a开发者_开发技巧void 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?


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消