diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -307,20 +307,24 @@
 Each module that uses at least one of the `inline-c` functions gets a C
 file associated to it, where the filename of said file will be the same
 as the module but with a C extension.  This C file must be built after
-the Haskell code and linked appropriately.  If you use cabal, all you
-have to do is declare each associated C file in the `.cabal` file and
-you are good.
+the Haskell code and linked appropriately.
 
+If you use cabal, you **must** manually declare each associated C file in
+the `c-sources` section of the `.cabal` file and you are good.
+
 For example we might have
 
 ```
 executable foo
   main-is:             Main.hs, Foo.hs, Bar.hs
   hs-source-dirs:      src
+
+  -- IMPORTANT!
   -- Here the corresponding C sources must be listed for every module
   -- that uses C code.  In this example, Main.hs and Bar.hs do, but
   -- Foo.hs does not.
   c-sources:           src/Main.c, src/Bar.c
+
   -- These flags will be passed to the C compiler
   cc-options:          -Wall -O2
   -- Libraries to link the code with.
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,4 @@
+- 0.5.6.0: Add `ForeignPtr` anti-quoter
 - 0.5.5.9: Make tests work with QuickCheck < 2.9
 - 0.5.5.8: Add workaround for QuickCheck-2.9 bug. See issue #51
 - 0.5.5.2: Add docs regarding internals. See issue #41.
diff --git a/inline-c.cabal b/inline-c.cabal
--- a/inline-c.cabal
+++ b/inline-c.cabal
@@ -1,5 +1,5 @@
 name:                inline-c
-version:             0.5.5.9
+version:             0.5.6.0
 synopsis:            Write Haskell source files including C code inline. No FFI required.
 description:         See <https://github.com/fpco/inline-c/blob/master/README.md>.
 license:             MIT
diff --git a/src/Language/C/Inline.hs b/src/Language/C/Inline.hs
--- a/src/Language/C/Inline.hs
+++ b/src/Language/C/Inline.hs
@@ -25,6 +25,7 @@
     -- * Contexts
     Context
   , baseCtx
+  , fptrCtx
   , funCtx
   , vecCtx
   , bsCtx
diff --git a/src/Language/C/Inline/Context.hs b/src/Language/C/Inline/Context.hs
--- a/src/Language/C/Inline/Context.hs
+++ b/src/Language/C/Inline/Context.hs
@@ -35,6 +35,7 @@
     -- * 'Context'
   , Context(..)
   , baseCtx
+  , fptrCtx
   , funCtx
   , vecCtx
   , VecCtx(..)
@@ -55,6 +56,7 @@
 import qualified Data.Vector.Storable.Mutable as VM
 import           Data.Word (Word8, Word16, Word32, Word64)
 import           Foreign.C.Types
+import           Foreign.ForeignPtr (withForeignPtr)
 import           Foreign.Ptr (Ptr, FunPtr, freeHaskellFunPtr)
 import           Foreign.Storable (Storable)
 import qualified Language.Haskell.TH as TH
@@ -289,6 +291,24 @@
   case mbHsType of
     Nothing -> fail $ "Cannot convert C type (" ++ err ++ ")"
     Just hsType -> return hsType
+
+-- | This 'Context' adds support for 'ForeignPtr' arguments. It adds a unique
+-- marshaller called @fptr-ptr@. For example, @$fptr-ptr:$(int *x)@ extracts the
+-- bare C pointer out of foreign pointer @x@.
+fptrCtx :: Context
+fptrCtx = mempty
+  { ctxAntiQuoters = Map.fromList [("fptr-ptr", SomeAntiQuoter fptrAntiQuoter)]
+  }
+
+fptrAntiQuoter :: AntiQuoter HaskellIdentifier
+fptrAntiQuoter = AntiQuoter
+  { aqParser = cDeclAqParser
+  , aqMarshaller = \purity cTypes cTy cId -> do
+      hsTy <- convertType_ "fptrCtx" purity cTypes cTy
+      hsExp <- getHsVariable "fptrCtx" cId
+      hsExp' <- [| withForeignPtr $(return hsExp) |]
+      return (hsTy, hsExp')
+  }
 
 -- | This 'Context' includes a 'AntiQuoter' that removes the need for
 -- explicitely creating 'FunPtr's, named @"fun"@.
diff --git a/test/tests.c b/test/tests.c
--- a/test/tests.c
+++ b/test/tests.c
@@ -146,12 +146,7 @@
 }
 
 
-int inline_c_Main_22_dbf060cb8fa2b86c6c6838ef9b645ac20f38ba79(int _e4_inline_c_0) {
-return ( _e4_inline_c_0 );
-}
-
-
-int inline_c_Main_23_2421969c444755bea2c6f2060e0921ce7f3d16d7(int PreludemaxBound_2e_inline_c_0) {
-return ( PreludemaxBound_2e_inline_c_0 );
+int inline_c_Main_22_a3bae806835fddf243d045e57f2ba979bc7961cc(int foobar_inline_c_0) {
+return ( foobar_inline_c_0 );
 }
 
diff --git a/test/tests.hs b/test/tests.hs
--- a/test/tests.hs
+++ b/test/tests.hs
@@ -6,6 +6,8 @@
 import           Data.Monoid ((<>))
 import qualified Data.Vector.Storable.Mutable as V
 import           Foreign.C.Types
+import           Foreign.ForeignPtr (mallocForeignPtrBytes)
+import           Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
 import qualified Language.Haskell.TH as TH
 import           Prelude
 import qualified Test.Hspec as Hspec
@@ -22,7 +24,7 @@
 
 import           Dummy
 
-C.context (C.baseCtx <> C.funCtx <> C.vecCtx <> C.bsCtx)
+C.context (C.baseCtx <> C.fptrCtx <> C.funCtx <> C.vecCtx <> C.bsCtx)
 
 C.include "<math.h>"
 C.include "<stddef.h>"
@@ -106,6 +108,10 @@
       let y = 9
       u32 <- [C.exp| uint32_t { $(uint32_t y) * 7 } |]
       u32 `Hspec.shouldBe` 63
+    Hspec.it "foreign pointer argument" $ do
+      fptr <- mallocForeignPtrBytes 32
+      ptr <- [C.exp| int* { $fptr-ptr:(int *fptr) } |]
+      ptr `Hspec.shouldBe` unsafeForeignPtrToPtr fptr
     Hspec.it "function pointer argument" $ do
       let ackermann m n
             | m == 0 = n + 1
