目标是避免在需要const wchar_t*
时复制字符串数据。是否可以在C++/CLI中获取指向String ^内部数组的指针?
答案似乎是肯定的,但函数PtrToStringChars
没有自己的MSDN条目(它只是在KB和博客中提到的一个技巧)。这让我很怀疑,我想和你们核对一下。使用该功能安全吗?
目标是避免在需要const wchar_t*
时复制字符串数据。是否可以在C++/CLI中获取指向String ^内部数组的指针?
答案似乎是肯定的,但函数PtrToStringChars
没有自己的MSDN条目(它只是在KB和博客中提到的一个技巧)。这让我很怀疑,我想和你们核对一下。使用该功能安全吗?
是的,没问题。它实际上有点documented但很难找到。 MSDN文档的C++库不是很好。它返回一个内部指针,这不适合转换为常量wchar_t *。您必须固定指针,以便垃圾回收器不能移动字符串。使用pin_ptr <>来做到这一点。
您可以使用Marshal :: StringToHGlobalUni()创建字符串的副本。如果wchar_t *需要长时间保持有效,请使用它。固定对象太长对于垃圾回收器来说不是很健康。
根据这篇文章:http://support.microsoft.com/kb/311259 PtrToStringChars正式支持,可以使用。它在vcclr.h中被描述为“获取内部gc指向包含在System :: String对象中的第一个字符”。
这是基于PtrToStringChars一个完整的解决方案,使用标准的C函数访问托管字符串内部,然后拷贝内容:
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;
}
我不会推荐'StringToHGlobalUni'。使用'PtrToStringChars'然后自己创建一个副本可能比搞乱HGLOBAL快很多,HGLOBAL是一个实际使用有限的专用分配器。实际上'marshal_as'或'marshal_as '将通过推荐本地副本。 http://msdn.microsoft.com/en-us/library/bb384865.aspx –
2010-06-21 03:16:07