Skip to content

NICTA/cplusplus-th

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cplusplus-th

cplusplus-th allows you to foreign import C++ functions that are compatible with the ccall calling convention. It also includes some standard library abstractions.

Example

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|]

Building

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

Standard Library

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.

Compatability

  • 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.