Last active
October 13, 2017 10:03
-
-
Save stla/65110168553fdc54cd55044eeafb65e8 to your computer and use it in GitHub Desktop.
Haskell FFI examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# 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]) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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