Pointer manipulations in Haskell
Some situations demand working with memory ponters. This may be the case when you are interfacing to anexternal library or working with disk data structures. Fortunately, Haskell provides the control you need to work wth pointers. This is a small example of how you can manage memory allocation and using it store priitive types.
We import the Foreign module.
>import Foreign
This allocates a byte buffer. Word8 is Haskell's primitive type for an octet. aAllocByteBuf allocates a byte buffer of specified size. The last part of the type signature of the method can be changed if you wanted to work with some other primitive type.
>allocByteBuf :: Int -> IO (Ptr Word8)
>allocByteBuf n
> = do buf <- mallocArray n
> return buf
putInt stores an integer in the buffer at specified offset. Note that the buffer we are working with is a byte buffer and castPtr cast it to the appropriate type. Unlike the cast operator in C, there is no type specified here. That information comes from the type of the value being stored and Haskell's type inference dedecues the type to cast to.
pokeElemOff stores the integer in the buffer at specified offset. If the architecture has any alignment requirements, the offset should honor that or you will get an error.
>putInt :: Ptr Word8 -> Int -> Int -> IO ()
>putInt buf offset i
> = do pokeElemOff (castPtr buf) offset i
> return ()
getInt is similar to putInt. Again, the type signature and castPtr work together to retrieve the integer value from the buffer.
>getInt :: Ptr Word8 -> Int -> IO Int
>getInt buf offset
> = do i <- peekElemOff (castPtr buf) offset
> return i
Here we exercise the functions above. Note the type signature attached to 255. Haskell can't dedeuce the type in all cases and requires you to disambiguate the type.
>main = do
> buf <- allocByteBuf 1024
> putInt buf 0 (255::Int)
> i <- getInt buf 0
> putStrLn $ "i: " ++ show i
> free buf
It is not clear if there a way to avoid writing get/put functions for each primitive type. Comments?
Sunday, February 22, 2009
Subscribe to:
Posts (Atom)