![](/img/trans.png)
[英]How to align in memory the array payload of a ByteArray# with GHC Haskell
[英]Copying GHC ByteArray# to Ptr
我正在嘗試編寫以下函數:
memcpyByteArrayToPtr ::
ByteArray# -- ^ source
-> Int -- ^ start
-> Int -- ^ length
-> Ptr a -- ^ destination
-> IO ()
行為應該是在內部使用memcpy
將ByteArray#
的內容復制到Ptr
。 我有兩種技術可以做這樣的事情,但我很難推斷他們的安全。
第一個是在內存包中找到的。 有一個輔助函數withPtr定義為:
data Bytes = Bytes (MutableByteArray# RealWorld)
withPtr :: Bytes -> (Ptr p -> IO a) -> IO a
withPtr b@(Bytes mba) f = do
a <- f (Ptr (byteArrayContents# (unsafeCoerce# mba)))
touchBytes b
return a
但是,我很確定這只是安全的,因為構造Bytes
的唯一方法是使用一個調用newAlignedPinnedByteArray#
的智能構造函數。 給出類似問題的答案和byteArrayContents#
的文檔表明,在處理固定的ByteArray#
s時它是安全的。 在我的情況下,我正在處理text
庫內部使用的ByteArray#
s,並且它們沒有固定,因此我認為這是不安全的。
我偶然發現的第二種可能性是text
本身。 在Data.Text.Array源代碼的底部,有一個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
已完成的text
。 最大的區別在於,不是傳遞MutableByteArray#
和ByteArray#
作為兩個指針,而是傳遞ByteArray#
和Ptr a
(或者可能是Addr#
,我不確定你通常使用哪個FFI)。
我建議安全嗎? 有沒有更好的方法可以讓我避免使用ffi? base
有什么東西可以做到這一點嗎? 請隨意更正我所做的任何錯誤假設,並感謝任何建議或指導。
copyByteArrayToAddr# :: ByteArray# -> Int# -> Addr# -> Int# -> State# s -> State# s
看起來像正確的primop。 您只需要確保不要嘗試將其復制到它占用的內存中。 所以你應該安全的
copyByteArrayToPtr :: ByteArray# -> Int -> Ptr a -> Int -> ST s ()
copyByteArrayToPtr ba (I# x) (Ptr p) (I# y) = ST $ \ s ->
(# copyByteArrayToAddr# ba x p y s, () #)
不幸的是,文檔讓我不知道每個Int#
應該是什么意思,但我想你可以通過試驗和段錯誤來解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.