간단한 예제를 위해 포인터에 오프셋을 추가하려고한다고 가정 해보십시오.
서문 :
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
withForeignPtr
내부에서 Ptr
에 유혹 될 수 있지만 내용은 해당에 대해 경고 :이 작업에서 포인터를 반환하고 작업이 완료된 후 사용하는 것이 안전하지
하는 것으로. 포인터의 모든 용도는 withForeignPtr
대괄호 안에 있어야합니다. 컴파일러는 개체가 아니라 ForeignPtr
개체의 사용을 추적 할 수 있기 때문에 finalizer는 예상보다 빨리 실행될 수 있습니다.
코드는 간단하다 :
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')
당신이 포인터 역 참조로 C에서 함수를 만들 수 있습니까? – kennytm