是否可以在 C++/CLI 中获取指向 String^ 内部数组的指针?

发布于 2024-09-06 09:38:43 字数 250 浏览 7 评论 0原文

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦明 2024-09-13 09:38:43

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

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;
}
弥繁 2024-09-13 09:38:43

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文