【问题标题】:make IntPtr in C#.NET point to string value使 C#.NET 中的 IntPtr 指向字符串值
【发布时间】:2012-06-20 20:53:06
【问题描述】:

我正在使用一个具有 StringHandle 字段的类,该字段是一个 IntPtr 值,代表一个 LPCWSTR 在 C++ 中。

internal IntPtr StringHandle; // LPCWSTR

现在说我有一个字符串:string x = "abcdefg"

如何使用 String 句柄指向 String 的开头,使其像 C++ LPCWSTR 一样?

【问题讨论】:

  • 我正在使用仅存在于本机代码 (C++) 中的接口,因此我使用的是来自 .NET 的互操作。但是,具有 StringHandle 的类不是我的,我不想更改。
  • 因为这是他正在使用的图书馆所期望的。并非所有东西都有为其构建的 .NET 包装器,即使在框架内,当您处理低级 Windows 消息之类的事情时,Marshal 类也可以得到很好的使用。

标签: c# .net pointers interop


【解决方案1】:

您需要先将字符串复制到非托管内存,然后从该位置获取IntPtr。你可以这样做:

IntPtr strPtr = Marshal.StringToHGlobalUni(x);

另外,您需要确保释放非托管内存:

Marshal.FreeHGlobal(strPtr);

最好在 try/finally 中完成所有这些操作。

【讨论】:

  • 我实际上需要这个 Marshal.StringToCoTaskMemUni,因为我使用的是 COM,但谢谢
【解决方案2】:

当垃圾收集器压缩堆时,内存中的托管字符串移动。所以它们没有稳定的地址,不能直接转换为 LPCWSTR。您需要使用 GCHandle.Alloc() 固定字符串以使用 GCHandle.AddrOfPinnedObject 或使用 Marshal.StringToHGlobalUni() 将其复制到非托管内存中。

如果地址需要稳定一段时间,强烈建议复制。

【讨论】:

【解决方案3】:

您想在 Marshal 类上使用 StringTo* 方法之一

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2011-04-12
    • 1970-01-01
    • 2013-02-16
    • 2015-05-19
    • 2011-09-24
    • 1970-01-01
    相关资源
    最近更新 更多