问题
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?
回答1:
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.
回答2:
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;
}
回答3:
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 .
来源:https://stackoverflow.com/questions/3046137/is-it-possible-to-get-a-pointer-to-strings-internal-array-in-c-cli