将托管引用存储在非托管内存中

Posted

技术标签:

【中文标题】将托管引用存储在非托管内存中【英文标题】:Store a managed reference in unmanaged memory 【发布时间】:2014-12-17 23:22:23 【问题描述】:

是否可以在非托管内存区域中存储对常规托管对象(未固定)的引用?本质上,我不想固定对象,而是将该区域标记为 GC 根或类似的东西。我查看了 GCHandle 文档,但不清楚它是否真的可以做到这一点。

【问题讨论】:

据我所知 所有 非固定对象可以移动,相应的托管引用将被修补......即使你找到内部的东西我也不会依赖关于这种行为... 需要 GCHandle,因此无法收集对象。它的 ToIntPtr() 方法提供了一种方法来生成可以存储在非托管内存中的值。使用 FromIntPtr() 和 Target 转换回来。您可以使用 C++/CLI 中的 gcroot 类自动完成所有这些操作。 @HansPassant:是的,但是当您可以通过该接口将该指针值存储在任何随机位置时,我看不出 GCHandle 怎么可能提供这样的功能。那么当对象移动时如何更新指针呢?还是我们真的在谈论某种句柄/其他间接? ToIntPtr() 生成的 IntPtr 提供对句柄的引用,而不是对象。手柄不会移动,只有对象会移动。 啊,我明白了,这更有意义。然后 Free() 大概会释放这个备用句柄? 【参考方案1】:

是的,GCHandle 可以做到这一点。唯一的缺点是它是无类型的,但这不是一个大问题,因为它很简单,可以围绕 GCHandle 创建一个有类型的包装器。

【讨论】:

以上是关于将托管引用存储在非托管内存中的主要内容,如果未能解决你的问题,请参考以下文章

转换为C ++ CLI托管对象引用的本机指针?

如何在非托管 C++ 中捕获托管异常(来自委托)?

DebugBreak在非托管和混合(非托管+托管)应用程序之间有所不同?

c#泛型中非托管和结构约束之间的区别

如何在非托管 c++ dll 中查找调用方程序集名称

在非托管 C++ DLL 和托管 C# UI 之间发送信息