【问题标题】:Is it possible to get a pointer to String^'s internal array in C++/CLI?是否可以在 C++/CLI 中获取指向 String^ 内部数组的指针?
【发布时间】:2011-03-04 00:48:27
【问题描述】:

目标是在我需要const wchar_t* 时避免复制字符串数据。

答案似乎是肯定的,但是函数PtrToStringChars 没有自己的MSDN 条目(它只是在知识库和博客中作为技巧提及)。这让我很怀疑,我想和你们核实一下。使用该功能是否安全?

【问题讨论】:

    标签: string c++-cli wchar-t


    【解决方案1】:

    这是一个基于 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;
    }
    

    【讨论】:

      【解决方案2】:

      是的,没问题。它实际上有点documented,但很难找到。 C++ 库的 MSDN 文档不是很好。它返回一个内部指针,目前还不适合转换为 const wchar_t*。您必须固定指针,以便垃圾收集器无法移动字符串。使用 pin_ptr 来做到这一点。

      您可以使用 Marshal::StringToHGlobalUni() 来创建字符串的副本。如果 wchar_t* 需要长时间保持有效,请使用它。将对象固定太久对垃圾收集器来说不是很健康。

      【讨论】:

      • 我不推荐StringToHGlobalUni。使用 PtrToStringChars 然后自己制作副本可能比使用 HGLOBAL 快很多,HGLOBAL 是一种实际用途有限的专用分配器。实际上marshal_as&lt;BSTR&gt;marshal_as&lt;std::wstring&gt; 将被推荐为本地副本。 msdn.microsoft.com/en-us/library/bb384865.aspx
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多