如何在Haskell中获取指针值?

Chr*_*non 11 memory haskell pointers

我希望在非常低的水平上操纵数据.

因此,我有一个函数,它接收一个虚拟内存地址作为一个整数和"做东西"与此内存地址.我从C接口这个函数,所以它有类型(CUInt -> a).我要链接的内存是Word8一个文件.可悲的是,我不知道如何访问指针值Word8.

要清楚,我不需要Word8的值,我需要虚拟内存地址的值,这是指向它的指针的值.

Gre*_*con 7

为了一个简单的例子,假设你想为指针添加一个偏移量.

前面的事:

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以证明指针是有效的.你可能会被诱惑returnPtr,从里面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')