Skip to content

Instantly share code, notes, and snippets.

@stla
Last active October 13, 2017 10:03
Show Gist options
  • Save stla/65110168553fdc54cd55044eeafb65e8 to your computer and use it in GitHub Desktop.
Save stla/65110168553fdc54cd55044eeafb65e8 to your computer and use it in GitHub Desktop.
Haskell FFI examples
#include <stdlib.h> // to use calloc
double cfun (double x){
return x+1;
}
double foo (double *x){
return x[1];
}
double* bar (int n, double *arr){
double* y = calloc(n, sizeof(double));
for(int i=0; i<n; i++)
y[i] = arr[i]+1;
return y;
}
{-# LANGUAGE ForeignFunctionInterface #-}
module Lib where
import Foreign.C.Types
import Foreign (peek, newForeignPtr_)
import Foreign.Ptr
import System.IO.Unsafe (unsafePerformIO)
import qualified Data.Vector.Storable as SV
import Foreign.Marshal.Array (peekArray)
foreign import ccall "cfun" c_cfun :: CDouble -> CDouble
cfun :: Double -> Double
cfun d = realToFrac (c_cfun (realToFrac d))
-- https://stackoverflow.com/questions/9854782/can-the-ffi-deal-with-arrays-if-so-how
foreign import ccall "foo" c_foo :: Ptr CDouble -> CDouble
haskellFoo :: SV.Vector CDouble -> CDouble
haskellFoo sv = unsafePerformIO $ SV.unsafeWith sv (return . c_foo)
test_foo :: CDouble
test_foo = haskellFoo (SV.fromList [3,2,1])
foreign import ccall "bar" c_bar :: Ptr CInt -> Ptr CDouble -> Ptr CDouble
haskellBar :: SV.Vector CDouble -> IO [CDouble]
haskellBar sv = do
let n = SV.length sv
ptr <- SV.unsafeWith sv (return . (c_bar (fromIntegral n)))
peekArray n ptr
test_bar :: IO [CDouble]
test_bar = haskellBar (SV.fromList [3,2,1])
haskellBar2 :: SV.Vector CDouble -> IO (SV.Vector CDouble)
haskellBar2 sv = do
ptr <- SV.unsafeWith sv (return . c_bar)
fptr <- newForeignPtr_ ptr
return $ SV.unsafeFromForeignPtr0 fptr (SV.length sv)
test_bar2 :: IO (SV.Vector CDouble)
test_bar2 = haskellBar2 (SV.fromList [3,2,1])
name: testC
version: 0.1.0.0
-- synopsis:
-- description:
homepage: https://github.com/githubuser/testC#readme
license: BSD3
license-file: LICENSE
author: Author name here
maintainer: [email protected]
copyright: 2017 Author name here
category: Web
build-type: Simple
extra-source-files: README.md
cabal-version: >=1.10
extra-source-files: C/cfile.h
library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
, vector
default-language: Haskell2010
default-extensions: ForeignFunctionInterface
include-dirs: C
C-sources: C/cfile.c
source-repository head
type: git
location: https://github.com/githubuser/testC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment