簡體   English   中英

將GHC ByteArray#復制到Ptr

[英]Copying GHC ByteArray# to Ptr

我正在嘗試編寫以下函數:

memcpyByteArrayToPtr :: 
     ByteArray# -- ^ source
  -> Int -- ^ start
  -> Int -- ^ length
  -> Ptr a -- ^ destination
  -> IO ()

行為應該是在內部使用memcpyByteArray#的內容復制到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM