我希望在很低的水平上处理数据。
因此,我有一个函数,该函数接收虚拟内存地址作为整数,并使用该内存地址“处理”。我从C接口(interface)了此函数,因此它的类型为(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
编码,但是文档警告您不要这样做:代码很简单:
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')