diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2016-2017, Tim Matthews
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Tim Matthews nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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/clr-marshal.cabal b/clr-marshal.cabal
new file mode 100644
--- /dev/null
+++ b/clr-marshal.cabal
@@ -0,0 +1,26 @@
+name:                clr-marshal
+version:             0.1.0.0
+synopsis:            Marshaling for the clr
+description:         A common dependency for other clr packages, marshalling between Haskell & CLR data types.
+homepage:            https://gitlab.com/tim-m89/clr-haskell/tree/master/libs/clr-marshal
+cabal-version:       >=1.10
+build-type:          Simple
+license:             BSD3
+license-file:        LICENSE
+author:              Tim Matthews
+maintainer:          tim.matthews7@gmail.com
+copyright:           Copyright: (c) 2016-2017 Tim Matthews
+category:            Language, FFI, CLR, .NET
+
+source-repository head
+    type:            git
+    location:        https://gitlab.com/tim-m89/clr-haskell/tree/master
+
+library
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  exposed-modules:     Clr.Marshal
+                       Clr.Marshal.Host
+  build-depends:       base >= 4.7 && < 5
+                     , clr-host
+                     , text
diff --git a/src/Clr/Marshal.hs b/src/Clr/Marshal.hs
new file mode 100644
--- /dev/null
+++ b/src/Clr/Marshal.hs
@@ -0,0 +1,91 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE BangPatterns #-}
+module Clr.Marshal where
+
+import Clr.Host.BStr
+import Data.Coerce
+import Data.Text
+import Data.Text.Foreign
+import Data.Word
+
+import Foreign.Ptr
+import Foreign.Storable
+
+--
+-- Conversion from a high level Haskell type a a raw bridge type
+--
+class Marshal a b where
+  marshal :: a -> (b -> IO c) -> IO c
+
+--
+-- identity instance
+--
+instance {-# OVERLAPPABLE #-} (a ~ b) => Marshal a b where
+  marshal x f = f x
+
+--
+-- 2-tuple instance
+--
+instance {-# OVERLAPS #-} (Marshal a1 b1, Marshal a2 b2) => Marshal (a1, a2) (b1, b2) where
+  marshal (x1,x2) f = marshal x1 $ \x1'-> marshal x2 $ \x2'-> f (x1', x2')
+
+--
+-- 3-tuple instance
+--
+instance {-# OVERLAPS #-} (Marshal a1 b1, Marshal a2 b2, Marshal a3 b3) => Marshal (a1, a2, a3) (b1, b2, b3) where
+  marshal (x1,x2,x3) f = marshal x1 $ \x1'-> marshal x2 $ \x2'-> marshal x3 $ \x3'-> f (x1', x2', x3')
+
+--
+-- 4-tuple instance
+--
+instance {-# OVERLAPS #-} (Marshal a1 b1, Marshal a2 b2, Marshal a3 b3, Marshal a4 b4) => Marshal (a1, a2, a3, a4) (b1, b2, b3, b4) where
+  marshal (x1,x2,x3,x4) f = marshal x1 $ \x1'-> marshal x2 $ \x2'-> marshal x3 $ \x3'-> marshal x4 $ \x4'-> f (x1', x2', x3', x4')
+
+--
+-- 5-tuple instance
+--
+instance {-# OVERLAPS #-} (Marshal a1 b1, Marshal a2 b2, Marshal a3 b3, Marshal a4 b4, Marshal a5 b5) => Marshal (a1, a2, a3, a4, a5) (b1, b2, b3, b4, b5) where
+  marshal (x1,x2,x3,x4,x5) f = marshal x1 $ \x1'-> marshal x2 $ \x2'-> marshal x3 $ \x3'-> marshal x4 $ \x4'-> marshal x5 $ \x5'-> f (x1', x2', x3', x4', x5')
+
+--
+-- BStr instance
+--
+instance Marshal Text BStr where
+  marshal x f = do
+    bstr <- useAsPtr x (\p-> \l-> allocBStr p l)
+    !res <- f bstr
+    freeBStr bstr
+    return res
+
+instance Marshal String BStr where
+  marshal x f = marshal (pack x) f
+
+--
+-- Conversion from a raw bridge type of a methods result to a high level Haskell type
+--
+class Unmarshal a b where
+  unmarshal :: a -> IO b
+
+--
+-- Identity instance
+--
+instance {-# OVERLAPPABLE #-} a ~ b => Unmarshal a b where
+  unmarshal = return
+
+--
+-- BStr instances
+--
+instance Unmarshal BStr Text where
+  unmarshal x = do
+    let charSize = 2
+    let ptrData   = coerce x              :: Ptr Word16
+    let ptrLen    = plusPtr ptrData (-4)  :: Ptr Word16
+    lenBytes     <- peek ptrLen
+    !t <- fromPtr ptrData $ fromIntegral $ lenBytes `div` charSize
+    freeBStr x
+    return t
+
+instance Unmarshal BStr String where
+  unmarshal x = unmarshal x >>= return . unpack
diff --git a/src/Clr/Marshal/Host.hs b/src/Clr/Marshal/Host.hs
new file mode 100644
--- /dev/null
+++ b/src/Clr/Marshal/Host.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Clr.Marshal.Host where
+
+import Clr.Marshal
+
+import Clr.Host
+import Clr.Host.BStr
+
+import Data.Coerce
+import Data.Word
+import Foreign.Ptr
+
+-- | @'unsafeGetPointerToMethod' m@ returns a function pointer to the method @m@
+--  as implemented in the Salsa .NET driver assembly (Salsa.dll).  It is safe only
+--  if the type of the resulting function pointer matches that of the method given.
+unsafeGetPointerToMethod :: String -> IO (FunPtr a)
+unsafeGetPointerToMethod methodName = do
+  result <- marshal methodName $ \(methodName'::BStr) -> getPointerToMethodRaw >>= \f-> f $ coerce methodName'
+  if result == nullFunPtr
+    then error $ "Unable to execute Salsa.dll method '" ++ methodName ++ "'."
+    else return result
+
+getPointerToMethodRaw :: IO (GetPtrToMethod a)
+getPointerToMethodRaw = getPtrToMethod_get >>= return . makeGetPtrToMethod
+
+foreign import ccall "dynamic" makeGetPtrToMethod :: GetPtrToMethodFunPtr a -> GetPtrToMethod a
+
+-- | @'getMethodStub' c m s@ returns a function pointer to a function that, when
+--   called, invokes the method with name @m@ and signature @s@ in class @c@.
+--
+--   @s@ should be a semi-colon delimited list of parameter types indicating the
+--   desired overload of the given method.
+getMethodStub :: String -> String -> String -> IO (FunPtr f)
+getMethodStub className methodName parameterTypeNames = do
+  marshal className $ \className' ->
+    marshal methodName $ \methodName' ->
+      marshal parameterTypeNames $ \parameterTypeNames' ->
+        getMethodStubRaw >>= \f-> return $ f className' methodName' parameterTypeNames'
+
+getMethodStubRaw :: IO (GetMethodStubDelegate a)
+getMethodStubRaw = unsafeGetPointerToMethod "GetMethodStub" >>= return . makeGetMethodStubDelegate
+
+type GetMethodStubDelegate a = BStr -> BStr -> BStr -> FunPtr a
+foreign import ccall "dynamic" makeGetMethodStubDelegate :: FunPtr (GetMethodStubDelegate a) -> GetMethodStubDelegate a
+
+
