diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+The MIT License (MIT)
+Copyright (c) 2016-2017 Tao He
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/c2hs-extra.cabal b/c2hs-extra.cabal
new file mode 100644
--- /dev/null
+++ b/c2hs-extra.cabal
@@ -0,0 +1,23 @@
+name:                       c2hs-extra
+version:                    0.1.0.0
+synopsis:                   Convenient marshallers for complicate C types.
+description:                Convenient marshallers for complicate C types.
+homepage:                   http://github.com/sighingnow/mxnet-haskell#readme
+license:                    MIT
+license-file:               LICENSE
+author:                     Tao He
+maintainer:                 sighingnow@gmail.com
+copyright:                  Copyright: (c) 2016-2017 Tao He
+category:                   Development, Foreign
+build-type:                 Simple
+cabal-version:              >= 1.10
+
+Library
+    exposed-modules:
+        C2HS.C.Extra.Marshal
+    other-modules:
+    hs-source-dirs:         src
+    build-tools:            c2hs
+    ghc-options:            -Wall
+    default-language:       Haskell2010
+    build-depends:          base >= 4.7 && < 5.0
diff --git a/src/C2HS/C/Extra/Marshal.hs b/src/C2HS/C/Extra/Marshal.hs
new file mode 100644
--- /dev/null
+++ b/src/C2HS/C/Extra/Marshal.hs
@@ -0,0 +1,56 @@
+-----------------------------------------------------------
+-- |
+-- module:                      C2HS.C.Extra.Marshal
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- Convenient marshallers for complicate C types.
+--
+module C2HS.C.Extra.Marshal
+    ( peekIntegral
+    , peekString
+    , peekStringArray
+    , withStringArray
+    , withIntegralArray
+    ) where
+
+import Foreign.C.String ( peekCString, withCString )
+import Foreign.C.Types ( CChar, CInt, CUInt )
+import Foreign.Marshal.Array ( peekArray, withArray )
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable, peek )
+
+-- | Peek from pointer then cast to another integral type.
+peekIntegral :: (Integral a, Storable a, Integral b) => Ptr a -> IO b
+peekIntegral = (fromIntegral <$>) . peek
+
+{-# SPECIALIZE peekIntegral :: Ptr CInt -> IO Int #-}
+
+-- | Peek string from a two-dimension pointer of CChar.
+peekString :: Ptr (Ptr CChar) -> IO String
+peekString p = peek p >>= peekCString
+
+-- | Peek an array of String and the result's length is given.
+peekStringArray :: Integral n => n -> Ptr (Ptr CChar) -> IO [String]
+peekStringArray n p = peekArray (fromIntegral n) p >>= mapM peekCString
+
+{-# SPECIALIZE peekStringArray :: Int -> Ptr (Ptr CChar) -> IO [String] #-}
+{-# SPECIALIZE peekStringArray :: CUInt -> Ptr (Ptr CChar) -> IO [String] #-}
+
+-- | Use an array of String as argument, usually used to pass multiple names to C
+-- functions.
+withStringArray :: [String] -> (Ptr (Ptr CChar) -> IO a) -> IO a
+withStringArray ss f = do
+    ps <- mapM (\s -> withCString s return) ss
+    withArray ps f
+
+-- | Use an array of Integral as argument.
+withIntegralArray :: (Integral a, Integral b, Storable b) => [a] -> (Ptr b -> IO c) -> IO c
+withIntegralArray ns f = do
+    let ns' = fmap fromIntegral ns
+    withArray ns' f
+
+{-# SPECIALIZE withIntegralArray :: [Int] -> (Ptr CInt -> IO c) -> IO c #-}
+{-# SPECIALIZE withIntegralArray :: [CInt] -> (Ptr CInt -> IO c) -> IO c #-}
+{-# SPECIALIZE withIntegralArray :: [CUInt] -> (Ptr CUInt -> IO c) -> IO c #-}
