cplusplus-th
allows you to foreign import C++ functions that are
compatible with the ccall
calling convention. It also includes
some standard library abstractions.
With the following C++ function in the object file cbits/string.o
:
namespace haskell {
string* fromCString(char const* x, int length) {
return new string(x, length);
}
}
We can import it into Haskell with:
cplusplus "haskell::fromCString(char const*, int)" "cbits/string.o"
[t|CString -> Int -> IO Std__basic_string|]
It works by looking up the symbol in the object file.
When using cabal, it is recommended you include the C++ file in
your c-sources
and compile it in a build hook. For example:
import Distribution.Simple
import Distribution.Simple.Setup
import Distribution.Simple.Program
import Distribution.Simple.Program.Types
import Distribution.Simple.LocalBuildInfo
import Distribution.PackageDescription
cc_flags = ["-stdlib=libc++", "-o", "cbits/string.o", "-c", "cbits/string.cc"]
main :: IO ()
main = defaultMainWithHooks simpleUserHooks {
buildHook = buildCPlusPlus
}
buildCPlusPlus :: PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
buildCPlusPlus pkg buildInfo hooks flags = do
let verb = fromFlag (buildVerbosity flags)
clang <- findProgramLocation verb "clang++"
let clang' = case clang of
Just x -> x
Nothing -> error "clang++ not on path"
runProgram verb (simpleConfiguredProgram "clang++" (FoundOnSystem clang')) cc_flags
buildHook simpleUserHooks pkg buildInfo hooks flags
Foreign.CPlusPlusStdLib
exports the following type class:
class CPlusPlusLand a {- haskell side -} b {- c++ side -} where
to :: a -> IO b
from :: b -> IO a
To avoid orphan instances, it implements instances for
some numeric types, String
and ByteString
.
- Static functions are simply the arguments.
- Static member functions take the object as the first argument.
- Functions via a vtable are not possible.
- Inline functions are not possible.
- instantiating templates is not possible.