目標は、必要なときに文字列データをコピーしないようにすることconst wchar_t*
です。
答えはイエスのようですが、関数にPtrToStringChars
は独自の MSDN エントリがありません (KB とブログでトリックとしてのみ言及されています)。疑問に思ったので、皆さんに確認したいと思います。その機能を使用しても安全ですか?
目標は、必要なときに文字列データをコピーしないようにすることconst wchar_t*
です。
答えはイエスのようですが、関数にPtrToStringChars
は独自の MSDN エントリがありません (KB とブログでトリックとしてのみ言及されています)。疑問に思ったので、皆さんに確認したいと思います。その機能を使用しても安全ですか?
管理された文字列の内部にアクセスし、標準の C 関数を使用して内容をコピーする PtrToStringChars に基づく完全なソリューションを次に示します。
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;
}
はい、問題ありません。実際にはある程度文書化されていますが、見つけるのは困難です。C++ ライブラリの MSDN ドキュメントはあまり良くありません。const wchar_t* への変換にはまだ適していない内部ポインターを返します。ガベージ コレクターが文字列を移動できないように、ポインターを固定する必要があります。これを行うには、pin_ptr<> を使用します。
Marshal::StringToHGlobalUni() を使用して、文字列のコピーを作成できます。wchar_t* を長期間有効にしておく必要がある場合は、代わりにそれを使用してください。オブジェクトをあまりにも長く固定することは、ガベージ コレクターにとってあまり健康的ではありません。