TLDR -- Calling D code from Haskell through the FFI works with
DMD but not with GDC or LDC2.
The time consuming version:
Since D allows C to directly call it, if the D code is wrapped in
extern (C){ ... }, I thought it should be possible to call such D
code from Haskell using the FFI.
The FFI in Haskell allows directly calling C code given a header
file, the name of a function, and its C-type. So I made a D file
with the functions I want to call, FunctionsInD.d
extern (C){
int d_f(int x){
return x+2;
}
int d_g(int x, int y){
return x+y;
}
}
Then made a header file, FunctionsInD.h
int d_f(int x);
int d_g(int x, int y);
Then the Haskell wrapper ToD.hs:
module ToD where
import Foreign.C
foreign import ccall "FunctionsInD.h d_f"
c_f :: CInt -> CInt
foreign import ccall "FunctionsInD.h d_g"
c_g :: CInt -> CInt -> CInt
h_f :: Int -> Int -- the "pure" haskell version
h_f x = fromIntegral (c_f (fromIntegral x))
h_g :: Int -> Int -> Int
h_g x y = fromIntegral (c_g (fromIntegral x) (fromIntegral y))
For reasons I don't completely understand, you also need a fake
main function, dummy.d:
void main(){}
And a driver for test, Main.hs:
module Main where
import ToD
main :: IO ()
main = do
let (a,b) = (h_f 3, h_g 3 4)
sequence_ [putStrLn (show a), putStrLn (show b)]
To put this all together, here is the makefile.
DC = dmd
# DC = ldc2
# DC = ldmd2
# DC = gdc
main: FunctionsInD.o FunctionsInD.h dummy.o
ghc Main.hs --make -o main_ffi_test FunctionsInD.o
dummy.o -lphobos2
clean:
rm FunctionsInD.o dummy.o main_ffi_test
FunctionsInD.o FunctionsInD.d:
$(DC) -c FunctionsInD.d
dummy.o: dummy.d
$(DC) -c dummy.d
The question: if I comment out DC=dmd, and uncomment any of the
other options, the build fails. The problem is that ghc
complains of multiple definitions of main (not with DMD only GDC
and LDC2). If I remove dummy.o from the ghc line, I get,
undefined reference to _DMain.
But wait! It gets weirder. I can compile FunctionsInD.d with
GDC or LDC2, as long as I compile dummy.d with DMD, everything
works fine.
Once I get through this hump, I will try to get on with more
interesting interfaces, like strings and structs.