我希望在非常低的水平上處理數據。如何在Haskell中獲取指針值?
因此,我有一個函數接收虛擬內存地址作爲一個整數和「做東西」這個內存地址。我從C接口這個函數,所以它的類型爲(CUInt -> a)
。 我想鏈接的內存是文件中的Word8
。可悲的是,我不知道如何訪問指向Word8
的指針值。
要清楚,我不需要Word8的值,我需要虛擬內存地址的值,它是指向它的指針的值。
我希望在非常低的水平上處理數據。如何在Haskell中獲取指針值?
因此,我有一個函數接收虛擬內存地址作爲一個整數和「做東西」這個內存地址。我從C接口這個函數,所以它的類型爲(CUInt -> a)
。 我想鏈接的內存是文件中的Word8
。可悲的是,我不知道如何訪問指向Word8
的指針值。
要清楚,我不需要Word8的值,我需要虛擬內存地址的值,它是指向它的指針的值。
爲了一個簡單的例子,假設你想給指針添加一個偏移量。
前面的問題:
module Main where
import Control.Monad (forM_)
import Data.Char (chr)
import Data.Word (Word8)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.Storable (peek)
import System.IO.MMap (Mode(ReadOnly), mmapFileForeignPtr)
是的,你寫的,你不希望Word8
的價值,但我已經對peek
檢索它表明指針是有效的。你也許會return
的Ptr
從內withForeignPtr
,但文檔警告不要說:
請注意,這不是安全地從動作返回指針和行動完成後使用它。指針的所有用途應位於
withForeignPtr
括號內。這種不安全的原因與下面的unsafeForeignPtrToPtr
相同:終結器的運行時間可能比預期的要早,因爲編譯器只能跟蹤ForeignPtr
對象的使用情況,而不能跟蹤由此產生的Ptr
對象。
的代碼很簡單:
doStuff :: ForeignPtr Word8 -> Int -> IO()
doStuff fp i =
withForeignPtr fp $ \p -> do
let addr = p `plusPtr` i
val <- peek addr :: IO Word8
print (addr, val, chr $ fromIntegral val)
爲了接近從你的問題「的文件一Word8
」,主程序內存映射文件,並使用該緩衝區做的東西與內存地址。
main :: IO()
main = do
(p,offset,size) <- mmapFileForeignPtr path mode range
forM_ [0 .. size-1] $ \i -> do
doStuff p (offset + i)
where
path = "/tmp/input.dat"
mode = ReadOnly
range = Nothing
-- range = Just (4,3)
輸出:
(0x00007f1b40edd000,71,'G') (0x00007f1b40edd001,117,'u') (0x00007f1b40edd002,116,'t') (0x00007f1b40edd003,101,'e') (0x00007f1b40edd004,110,'n') (0x00007f1b40edd005,32,' ') (0x00007f1b40edd006,77,'M') (0x00007f1b40edd007,111,'o') (0x00007f1b40edd008,114,'r') (0x00007f1b40edd009,103,'g') (0x00007f1b40edd00a,101,'e') (0x00007f1b40edd00b,110,'n') (0x00007f1b40edd00c,33,'!') (0x00007f1b40edd00d,10,'\n')
您可能在尋找ptrToIntPtr或者fromIntegral以使其成爲CUInt。
請注意,雖然CUInt不能在所有平臺上表示指針。
你不能讓C中的函數取消引用指針? – kennytm 2010-03-05 12:30:39