Por un simple ejemplo, digamos que desea agregar un desplazamiento al puntero.
Información preliminar:
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)
Sí, se escribió que no desea que el valor de la Word8
, pero he recuperado con peek
para demostrar que el puntero es válido. Usted puede verse tentado a return
la Ptr
withForeignPtr
desde el interior, pero la documentación que advierte contra:
en cuenta que no es seguro regresar el puntero de la acción y utilizarlo después de la acción completa. Todos los usos del puntero deben estar dentro del soporte withForeignPtr
. La razón de esta inseguridad es la misma que para unsafeForeignPtrToPtr
a continuación: el finalizador puede ejecutarse antes de lo esperado, porque el compilador solo puede rastrear el uso del objeto ForeignPtr
, no un objeto Ptr
hecho a partir de él.
El código es sencillo:
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)
para aproximar “un Word8
en un archivo” de su pregunta, el programa principal mapea en memoria un archivo y utiliza ese búfer hacer cosas con las direcciones de memoria.
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)
Salida:
(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')
¿No puedes hacer una función en C para eliminar la referencia al puntero? – kennytm