我想寫以下功能:複製GHC的ByteArray#到PTR
memcpyByteArrayToPtr ::
ByteArray# --^source
-> Int --^start
-> Int --^length
-> Ptr a --^destination
-> IO()
行爲應該是內部使用memcpy
到ByteArray#
的內容複製到Ptr
。我有兩種技術可以做這樣的事情,但是我很難推斷他們的安全性。
第一個發現在memory包中。有一個輔助功能withPtr定義爲:
data Bytes = Bytes (MutableByteArray# RealWorld)
withPtr :: Bytes -> (Ptr p -> IO a) -> IO a
withPtr [email protected](Bytes mba) f = do
a <- f (Ptr (byteArrayContents# (unsafeCoerce# mba)))
touchBytes b
return a
但是,我敢肯定,這僅僅是安全的,因爲構建Bytes
的唯一途徑是通過調用newAlignedPinnedByteArray#
一個聰明的構造函數。 An answer given to a similar question和docs for byteArrayContents#
表明只有在處理固定的ByteArray#
時纔是安全的。在我的情況下,我正在處理,即text
庫uses internally,並且它們沒有固定,所以我認爲這將是不安全的。
我偶然發現的第二種可能性是text
本身。在Data.Text.Array source code的底部,有一個FFI功能memcpyI
:
foreign import ccall unsafe "_hs_text_memcpy" memcpyI
:: MutableByteArray# s -> CSize -> ByteArray# -> CSize -> CSize -> IO()
這是由下面的C代碼的支持:
void _hs_text_memcpy(void *dest, size_t doff, const void *src, size_t soff, size_t n)
{
memcpy(dest + (doff<<1), src + (soff<<1), n<<1);
}
由於它的text
的一部分,我相信這是安全的,它看起來很危險,因爲它是從未固定的ByteArray#
獲取內存位置,這是byteArrayContents#
文檔警告的內容。我認爲沒關係,因爲ffi呼叫被標記爲不安全,我認爲這阻止GC在ffi呼叫期間移動ByteArray#
。
這就是我所做的研究。到目前爲止,我最好的猜測是我可以複製text
中已完成的工作。最大的區別是,我不會傳入MutableByteArray#
和ByteArray#
作爲兩個指針,而是通過ByteArray#
和Ptr a
(或者可能是Addr#
,我不確定您通常使用哪些ffi)。
我建議安全嗎?有沒有更好的方法可以讓我避免使用ffi? base
中有沒有這樣做?隨時糾正我做出的任何不正確的假設,並感謝您的任何建議或指導。
'copyByteArrayToAddr#:: ByteArray# - > Int# - > Addr# - > Int# - > State#s - > State#s'看起來很有希望。雖然文檔似乎缺少了一些單詞,但它的有效性有點不明確。 「複製ByteArray的範圍。ByteArray必須包含指定的範圍,但不會被選中。 Addr#不能指向ByteArray被固定),但是這也沒有被選中。「 – dfeuer
啊,這只是一個Haddock問題。源代碼說:」Addr#不能指向MutableByteArray#(例如,如果MutableByteArray# 「 – dfeuer
非常好,看起來它應該是安全的,如果你想將你的評論轉換爲答案,我會接受它,如果不是,我會將它轉換成並且接受它 –