     GDT_CFloat64 -> Just . Block <$> (readIt b x y :: IOVector (Complex Double))
     _            -> return Nothing
   where
-    readIt :: Storable a => Band -> Int -> Int -> IOVector a
+    readIt :: Storable a => Band b -> Int -> Int -> IOVector a
     readIt b x y = do
       f <- mallocForeignPtrArray (bandBlockLen b)
       withForeignPtr f $ \ptr ->
         throwIfError "could not read block" $
-          {#call GDALReadBlock as ^#}
-            b (fromIntegral x) (fromIntegral y) (castPtr ptr)
+          readBlock_ b (fromIntegral x) (fromIntegral y) (castPtr ptr)
       return $ unsafeFromForeignPtr0 f (bandBlockLen b)
 
+foreign import ccall safe "gdal.h GDALReadBlock" readBlock_
+    :: Band a -> CInt -> CInt -> Ptr () -> IO CInt
+
+
 type IOVector a = IO (Vector a)
 
 writeBandBlock :: (Storable a, Typeable a)
-  => Band
+  => RWBand
   -> Int -> Int
   -> Vector a
   -> IO ()

type MaybeIOVector a = IO (Maybe (Vector a))

readBandBlock :: (Storable a, Typeable a)
  => Band -> Int -> Int -> MaybeIOVector a
readBandBlock b x y = do
  block <- readBandBlock' b x y
  liftM (maybe Nothing (\(Block a) -> cast a)) $ readBandBlock' b x y


readBandBlock' :: Band -> Int -> Int -> IO (Maybe Block)
readBandBlock' b x y = 
  case bandDatatype b of
    GDT_Byte     -> Just . Block <$> (readIt b x y :: IOVector Word8)

  , DriverOptions
  , MajorObject
  , Dataset
  , RWDataset
  , RODataset
  , RWBand
  , ROBand
  , Band
  , Driver
  , ColorTable
