从 .NET 程序集透明地访问本机内存
Posted
技术标签:
【中文标题】从 .NET 程序集透明地访问本机内存【英文标题】:Access native memory transparently from .NET assembly 【发布时间】:2013-08-21 16:51:21 【问题描述】:我正在评估为允许以托管代码编写扩展的本机应用程序实现插件基础架构的可能性。这些插件将在本地堆上分配的大型(-ish)浮点缓冲区上运行,这些缓冲区在复制的内存占用方面相当昂贵。因此,插件应该能够直接在本机内存上进行操作。
据我了解,可以使用 Unsafe Code and Pointers 从托管代码访问本机内存(据我了解,这是 .NET 框架中唯一这样做的规定)。为了简化插件的开发,我宁愿不公开这个工件并提供代理机制,以便可以像托管集合一样访问缓冲区。
对于实现(例如,C++/CLI 互操作层很好)或特定的 .NET 运行时版本没有限制。缓冲区也可以假定为固定大小;插件只会修改内容。
是否有可能实施满足上述要求的基础设施?如果可以,有哪些选择?
【问题讨论】:
编写一个托管类,提供一个适合操作所述缓冲区的接口?所述类将在其内部使用指针和东西,但只公开安全托管位。 您可以提供 COM 可见并使 COM 对象处理非托管代码 【参考方案1】:是否有可能实施满足上述要求的基础设施?如果可以,有哪些选择?
您将无法直接将本机数据视为托管数组,但您可以通过 C++/CLI 公开一个层,允许直接、可索引地访问该内存。
例如,假设您有一个包含数百万个双精度浮点值的缓冲区。您可以轻松地创建一个 C++/CLI ref class
,通过索引器将一个窗口公开到该缓冲区,甚至更好,作为 IList<T>
。
这可能允许在 C# 中使用它,就像它是普通的 IList<T>
一样,无需复制数据,因为包装类只需要存储的缓冲内存位置。
【讨论】:
这基本上就是我所追求的,能够读取和写入本机内存而无需将此功能作为责任转发。一旦 C++/CLI 包装器通过构造IList<T>
对象(我可能错了),这听起来也没有涉及额外的托管-非托管转换。现在这将是完美的!
@IInspectable C++/CLI 实际上必须进行一些托管/非托管转换。如果这样做,您会发现通过纯托管路由访问时会有(非常轻微的)开销,但这通常比复制内存的成本要好得多,即使是在块中也是如此。
@IInspectable 我在我当前的项目中经常这样做,因为它确实是在混合模式程序集中干净地处理非常大的数据的唯一方法。以上是关于从 .NET 程序集透明地访问本机内存的主要内容,如果未能解决你的问题,请参考以下文章