diff --git a/Data/Array/CArray.hs b/Data/Array/CArray.hs
--- a/Data/Array/CArray.hs
+++ b/Data/Array/CArray.hs
@@ -19,17 +19,14 @@
 -- 'CArray' is similar to 'Data.Array.Unboxed.UArray' but slower if you stay
 -- within Haskell.  'CArray' can handle more types and can be used by external
 -- libraries.
+--
+-- 'CArray' has an instance of 'Binary'.
 -----------------------------------------------------------------------------
 
 module Data.Array.CArray (
     -- * CArray type
     CArray,
 
-    -- * Foreign support
-    withCArray,
-    unsafeForeignPtrToCArray,
-    createCArray,
-
     -- * Multi-dimensional
 
     -- ** Fast reshaping
@@ -76,6 +73,14 @@
     -- * Types
     Shapable,
     Abs,
+
+    -- * Unsafe low-level
+    withCArray,
+    unsafeForeignPtrToCArray,
+    toForeignPtr,
+    unsafeCArrayToByteString,
+    unsafeByteStringToCArray,
+    createCArray,
 
    -- * The overloaded immutable array interface
    module Data.Array.IArray
diff --git a/Data/Array/CArray/Base.hs b/Data/Array/CArray/Base.hs
--- a/Data/Array/CArray/Base.hs
+++ b/Data/Array/CArray/Base.hs
@@ -37,6 +37,8 @@
 import Data.Array.Base
 import Data.Array.MArray
 import Data.Array.IArray
+import qualified Data.ByteString.Internal as S
+import Data.Binary
 import Data.Complex
 import Data.List
 import System.IO.Unsafe         (unsafePerformIO)
@@ -86,7 +88,7 @@
     unsafeWrite (IOCArray _ _ _ fp) i e =
         withForeignPtr fp $ \a -> pokeElemOff a i e
 
--- |The pointer to the array contents is obtained by 'withCArray'.
+-- | The pointer to the array contents is obtained by 'withCArray'.
 -- The idea is similar to 'ForeignPtr' (used internally here).
 -- The pointer should be used only during execution of the 'IO' action
 -- retured by the function passed as argument to 'withCArray'.
@@ -96,13 +98,13 @@
 withIOCArray :: IOCArray i e -> (Ptr e -> IO a) -> IO a
 withIOCArray (IOCArray _ _ _ fp) f = withForeignPtr fp f
 
--- |If you want to use it afterwards, ensure that you
+-- | If you want to use it afterwards, ensure that you
 -- 'touchCArray' after the last use of the pointer,
 -- so the array is not freed too early.
 touchIOCArray :: IOCArray i e -> IO ()
 touchIOCArray (IOCArray _ _ _ fp) = touchForeignPtr fp
 
--- |Construct a 'CArray' from an arbitrary 'ForeignPtr'.  It is
+-- | /O(1)/ Construct a 'CArray' from an arbitrary 'ForeignPtr'.  It is
 -- the caller's responsibility to ensure that the 'ForeignPtr' points to
 -- an area of memory sufficient for the specified bounds.
 unsafeForeignPtrToCArray
@@ -110,11 +112,43 @@
 unsafeForeignPtrToCArray p (l,u) =
    return (CArray l u (rangeSize (l,u)) p)
 
+-- | /O(1)/ Construct a 'CArray' from an arbitrary 'ForeignPtr'.  It is
+-- the caller's responsibility to ensure that the 'ForeignPtr' points to
+-- an area of memory sufficient for the specified bounds.
 unsafeForeignPtrToIOCArray
    :: Ix i => ForeignPtr e -> (i,i) -> IO (IOCArray i e)
 unsafeForeignPtrToIOCArray p (l,u) =
    return (IOCArray l u (rangeSize (l,u)) p)
 
+-- | /O(1)/ Extract ForeignPtr from a CArray.
+toForeignPtr :: CArray i e -> (Int, ForeignPtr e)
+toForeignPtr (CArray _ _ n fp) = (n, fp)
+
+-- | /O(1)/ Turn a CArray into a ByteString.  Unsafe because it uses
+-- 'castForeignPtr' and thus is not platform independent.
+unsafeCArrayToByteString :: (Storable e) => CArray i e -> S.ByteString
+unsafeCArrayToByteString (CArray _ _ l fp) = go undefined l fp
+    where go :: (Storable e) => e -> Int -> ForeignPtr e -> S.ByteString
+          go dummy l fp = S.fromForeignPtr (castForeignPtr fp) 0 (l * sizeOf dummy)
+
+-- | /O(1)/ Turn a ByteString into a CArray.  Unsafe because it uses
+-- 'castForeignPtr' and thus is not platform independent.  Returns 'Nothing' if
+-- the range specified is larger than the size of the ByteString or the start of
+-- the ByteString does not fulfil the alignment requirement of the resulting
+-- CArray (as specified by the Storable instance).
+unsafeByteStringToCArray :: (Ix i, Storable e, IArray CArray e)
+                            => (i,i) -> S.ByteString -> Maybe (CArray i e)
+unsafeByteStringToCArray (l,u) bs = go undefined (l,u) bs
+    where go :: (Ix i, Storable e, IArray CArray e)
+                => e -> (i,i) -> S.ByteString -> Maybe (CArray i e)
+          go dummy (l,u) bs | safe = Just (CArray l u n fp)
+                            | otherwise = Nothing
+              where n = rangeSize (l,u)
+                    ((ForeignPtr addr contents), off, len) = S.toForeignPtr bs
+                    p@(Ptr addr') = Ptr addr `plusPtr` off
+                    fp = ForeignPtr addr' contents
+                    safe = sizeOf dummy * n <= len && p == p `alignPtr` alignment dummy
+
 copy :: (Ix i, Storable e) => CArray i e -> IO (CArray i e)
 copy ain@(CArray l u n fp) =
     createCArray (l,u) $ \op ->
@@ -604,3 +638,13 @@
 
 unsafeCreateCArray :: (Ix i, Storable e) => (i,i) -> (Ptr e -> IO ()) -> CArray i e
 unsafeCreateCArray lu =  unsafePerformIO . createCArray lu
+
+
+instance (Ix i, Binary i, Binary e, Storable e) => Binary (CArray i e) where
+    put a = do
+        put (bounds a)
+        mapM_ put (elems a)
+    get = do
+        lu <- get
+        es <- replicateM (rangeSize lu) get
+        return $ listArray lu es
diff --git a/carray.cabal b/carray.cabal
--- a/carray.cabal
+++ b/carray.cabal
@@ -1,5 +1,5 @@
 name:                carray
-version:             0.1.1
+version:             0.1.2
 synopsis:            A C-compatible array library.
 description:
 		     A C-compatible array library.
@@ -14,10 +14,23 @@
 author:              Jed Brown
 maintainer:          Jed Brown <jed@59A2.org>
 stability:	     experimental
-build-depends:       base, array
+cabal-version:       >=1.2
 build-type:	     Simple
-exposed-modules:     Data.Array.CArray
-		     Data.Array.IOCArray
-		     Data.Array.CArray.Base
-extensions:
-ghc-options:
+
+flag splitBase
+flag bytestringInBase
+
+library
+  if flag(bytestringInBase)
+    build-depends: base >= 2.0 && < 2.2, binary
+  else
+    build-depends: base < 2.0 || >= 3, bytestring, binary
+
+  if flag(splitBase)
+    build-depends: base >= 3, array, binary
+  else
+    build-depends: base < 3, binary
+
+  exposed-modules:   Data.Array.CArray
+                     Data.Array.IOCArray
+                     Data.Array.CArray.Base
