我有一个方法,它接受一个Memory<T>
对象。我想固定它,并将一个指向它的指针 * 独占地 * 存储在非托管内存中。我知道我可以通过使用memory.Pin()
创建一个MemoryHandle
,然后抓取memoryHandle.Pointer
来获得这个固定的指针。然而,因为我只想将它存储在非托管内存中,所以我需要确保内存句柄指向的托管对象在我完成它之前不会被收集。有没有一种方法可以在不收集底层对象的情况下将MemoryHandle
存储在非托管内存中,而不是在以后释放它?
我知道在理论上,这可以通过将GCHandle
存储在我的指针旁边而不是在我完成后处理它来完成。问题是我看不到任何从Memory
或MemoryHandle
对象中检索GCHandle
的方法,即使我很确定至少内存句柄内部包含GC句柄。所以,如果有办法从MemoryHandle
中得到GCHandle
,那将是这个问题的一个很好的解决方案。
3条答案
按热度按时间67up9zun1#
您可以使用
Marshal.StructureToPtr
和Marshal.PtrToStructure
将其封送。个字符
请注意,如果
Memory<T>
由MemoryManager
支持,那么句柄中将使用IPinnable
,这意味着它可能无法正确编组。b1zrtrql2#
我只是有一个想法,这可能可以通过将
GCHandle
存储到MemoryHandle
而不是底层对象本身来完成。类似于:字符串
我认为这是可行的,也是安全的,但是与仅仅将
GCHandle
放到底层对象的理论解决方案相比,感觉非常愚蠢,脆弱和丑陋。最大的真实的缺点是,这是以装箱分配(装箱MemoryHandle)为代价的,考虑到这是一个非常热的代码路径,我宁愿避免这一点。twh00eeo3#
这是我想出的解决方案。它是一个简单的 Package 器周围的
GCHandle
。有一个方法,创建句柄从一个MemoryHandle
在一个安全的方式,避免对象或GCHandle
分配在绝大多数情况下。重要的是,你不要处置MemoryHandle
你创建了UnmanagedMemoryHandle
。字符串