Chr*_*non 11 memory haskell pointers
我希望在非常低的水平上操纵数据.
因此,我有一个函数,它接收一个虚拟内存地址作为一个整数和"做东西"与此内存地址.我从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)
Run Code Online (Sandbox Code Playgroud)
是的,你写道你不想要的值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)
Run Code Online (Sandbox Code Playgroud)
要从Word8您的问题中近似"a in a File",主程序将对文件进行内存映射,并使用该缓冲区来处理内存地址.
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)
Run Code Online (Sandbox Code Playgroud)
输出:
(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')