在阅读了几个wiki和stackoverflow QA后,我留下了如何将GC分配的内存标记/传递区域传递给C库的问题.处理FFI的大多数库似乎首先分配内存,将值复制到其中并将其包装在Ptr类型中.问题是要保证在C库中花费时间时不会移动或取消分配内存.
假设我有一个类型为Text的myInput值,我想用C进行零拷贝FFI.我有什么选择?
到目前为止,我发现了以下内容:
https://wiki.haskell.org/Foreign_Function_Interface#Pointers_to_Haskell_data
在某些情况下,您可能希望为外部代码提供对稍后将检索的Haskell值的不透明引用.您需要确保在提供时间和检索时间之间不收集该值.为了做到这一点,已经创建了稳定的指针.您可以将值包装到StablePtr中并将其提供给外部代码(StablePtr是可编组的外部类型之一).
跟一些人交谈之后.他们告诉我StablePtr不应该被解除引用.并且主要用于传递void*.另一方面,wiki表示它适用于此目的,此答案也表示相同的/sf/answers/763048961/
有关StablePtr的更多信息:
https://www.well-typed.com/blog/2018/05/ghc-special-gc-objects/
在每个GC稳定指针更新后,指向它们在GC之前指向的Haskell对象的新位置
https://hackage.haskell.org/package/base-4.11.1.0/docs/Foreign-StablePtr.html#t:StablePtr
稳定指针是对Haskell表达式的引用,保证不受垃圾收集的影响,即,它既不会被释放,也不会在垃圾收集期间改变稳定指针本身的值(在垃圾收集期间可能会重新定位普通引用) ).因此,稳定的指针可以传递给外部代码,外部代码可以将其视为对Haskell值的不透明引用.
我想我可以用newStablePtr http://hackage.haskell.org/package/base-4.12.0.0/docs/Foreign-StablePtr.html#v:newStablePtr包装我的文本并完成它.我不明白StablePtr目前的情况.如果我可以将它用于此目的.如果不是它实际上用于什么.
然后有固定内存https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC/Pinned with ByteString
还有固定的ByteArray http://hackage.haskell.org/package/primitive-0.6.2.0/docs/Data-Primitive-ByteArray.html#g:2
只是ByteString和ByteArray的事情是,IO库通常提供自己的数据结构,并且必须先将数据复制到INTO ByteString/ByteArray中,这是我首先想要避免的.
也许有一些(不安全的)铸造功能?
这似乎是一个简单的问题,因为GC似乎已经能够将部分内存标记为"不移动"(固定).有没有一个函数我可以调用一个结构来切换这个标志?或者这个用例还有其他合适的功能吗?