Um ein einfaches Beispiel zu nennen, sagen Sie, dass Sie einen Offset zum Zeiger hinzufügen möchten.
Titelei:
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)
Ja, schrieben Sie, dass Sie den Wert des Word8
nicht wollen, aber ich habe es abgerufene mit peek
zu zeigen, dass der Zeiger gültig ist. Sie könnten die Ptr
von innen withForeignPtr
, aber die Dokumentation warnt vor, dass zu return
versucht sein:
Beachten Sie, dass es nicht sicher ist, den Zeiger von der Aktion zurückzukehren und es zu verwenden, nachdem die Aktion abgeschlossen ist. Alle Verwendungen des Zeigers sollten innerhalb der withForeignPtr
Klammer sein. Der Grund für diese Unsicherheit ist derselbe wie für unsafeForeignPtrToPtr
: Der Finalizer kann früher als erwartet ausgeführt werden, da der Compiler nur die Verwendung des Objekts ForeignPtr
verfolgen kann, kein Objekt Ptr
, das daraus hergestellt wurde.
Der Code ist unkompliziert:
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)
zu nähern „um ein Word8
in einer Datei“ aus Ihrer Frage, die Haupt-Programmspeicher-Karten eine Datei und verwendet diesen Puffer Material mit Speicheradressen zu tun.
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)
Ausgang:
(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')
Können Sie nicht eine Funktion in C zu dereferenzieren den Zeiger machen? – kennytm