Re: Haskell calling D code through the FFI

2014-08-06 Thread David Soria Parra via Digitalmars-d-learn
Jon via Digitalmars-d-learn digitalmars-d-learn@puremagic.com writes:

 So that does indeed solve some of the problems.  However, using this
 method, when linking I get two errors, undefined reference rt_init()
 and rt_term() I had just put these methods in the header file.  If I
 put wrappers around these functions and export I get the rt_init,
 rt_term is private.


rt_init is part of druntime. You need to link druntime into your program
in order to make it work.


Re: Haskell calling D code through the FFI

2014-08-06 Thread Jon via Digitalmars-d-learn
Hi, thank you!! I have modified the program based on a previous 
suggestion.  rt_init is called before using any D functionality 
and rt_term is called after using D functionality.  I did this by:
  1) Placing int rt_init(); and int rt_term(); into the header 
file that Haskell reads

  2) Creating Haskell stubs
   foreign import ccall unsafe FunctionsInD.h rt_init
   d_init :: IO CInt
   foreign import ccall unsafe FunctionsInD.h rt_term
   d_term :: IO CInt
And then in the Main haskell program, in main, the function 
starts with

d_init
and ends with
d_term
I'm pretty sure this is working nicely, because I can allocate 
structs with the new keyword in D, and this led to segfaults 
before using rt_init and rt_term.


I think the problem I was having was trying to do this in a 
stupid way i.e. put wrappers around init and term on the D side.


However, I still do not know how to compile without the using a 
fake main.  Compiling with -c -lib does still give me a _Dmain 
undefined reference.  I did

dmd -c -lib FunctionsInD.d
ghc --make Main.hs FunctionsInD.a -lphobos2
And get

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libphobos2.so: 
undefined reference to `_Dmain'


On Wednesday, 6 August 2014 at 11:03:33 UTC, David Soria Parra 
via Digitalmars-d-learn wrote:
Jon via Digitalmars-d-learn digitalmars-d-learn@puremagic.com 
writes:


So that does indeed solve some of the problems.  However, 
using this
method, when linking I get two errors, undefined reference 
rt_init()

and rt_term() I had just put these methods in the header file.
 If I
put wrappers around these functions and export I get the 
rt_init,

rt_term is private.



rt_init is part of druntime. You need to link druntime into 
your program

in order to make it work.




Re: Haskell calling D code through the FFI

2014-08-05 Thread David Soria Parra via Digitalmars-d-learn

On Monday, 4 August 2014 at 20:48:09 UTC, Jon wrote:

For reasons I don't completely understand, you also need a fake 
main function, dummy.d:


void main(){}



Note that this is not necessary if you compile with -lib e.g.:

  dmd -lib -oflibtest.a test.d

and then

  ghc Main.hs --make -omain libtest.a

I don't have gdc or ldc installed but as far as I know ldc has a 
-lib flag as well.


Re: Haskell calling D code through the FFI

2014-08-05 Thread Jon via Digitalmars-d-learn
Oh great thank you.  I think that might solve the majority of the 
confusion I was having.  One thing I can't figure out though, is 
getting garbage collection to work as expected.  If I have a 
function that allocates a pointer to a struct using new, I get an 
error on linking _dAlloc... not found.  But maybe compiling as a 
lib will solve this too.


On Tuesday, 5 August 2014 at 21:28:08 UTC, David Soria Parra 
wrote:

On Monday, 4 August 2014 at 20:48:09 UTC, Jon wrote:

For reasons I don't completely understand, you also need a 
fake main function, dummy.d:


   void main(){}



Note that this is not necessary if you compile with -lib e.g.:

  dmd -lib -oflibtest.a test.d

and then

  ghc Main.hs --make -omain libtest.a

I don't have gdc or ldc installed but as far as I know ldc has 
a -lib flag as well.




Re: Haskell calling D code through the FFI

2014-08-05 Thread Jon via Digitalmars-d-learn
So that does indeed solve some of the problems.  However, using 
this method, when linking I get two errors, undefined reference 
rt_init() and rt_term() I had just put these methods in the 
header file.  If I put wrappers around these functions and export 
I get the rt_init, rt_term is private.


On Tuesday, 5 August 2014 at 21:28:08 UTC, David Soria Parra 
wrote:

On Monday, 4 August 2014 at 20:48:09 UTC, Jon wrote:

For reasons I don't completely understand, you also need a 
fake main function, dummy.d:


   void main(){}



Note that this is not necessary if you compile with -lib e.g.:

  dmd -lib -oflibtest.a test.d

and then

  ghc Main.hs --make -omain libtest.a

I don't have gdc or ldc installed but as far as I know ldc has 
a -lib flag as well.




Re: Haskell calling D code through the FFI

2014-08-05 Thread safety0ff via Digitalmars-d-learn

On Tuesday, 5 August 2014 at 23:23:43 UTC, Jon wrote:
So that does indeed solve some of the problems.  However, using 
this method, when linking I get two errors, undefined reference 
rt_init() and rt_term() I had just put these methods in the 
header file.  If I put wrappers around these functions and 
export I get the rt_init, rt_term is private.




It works for me, here are the main parts of my Makefile:

DC = ~/bin/dmd

main: Main.hs FunctionsInD.a
ghc -o main Main.hs FunctionsInD.a ~/lib/libphobos2.a -lpthread

FunctionsInD.a: FunctionsInD.d
$(DC) -c -lib FunctionsInD.d

I passed in the phobos object directly because I don't know how 
to specify the ~/lib directory on the ghc command line.


Haskell calling D code through the FFI

2014-08-04 Thread Jon via Digitalmars-d-learn
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.


Re: Haskell calling D code through the FFI

2014-08-04 Thread safety0ff via Digitalmars-d-learn
Don't forget to call rt_init: 
http://dlang.org/phobos/core_runtime.html#.rt_init


Re: Haskell calling D code through the FFI

2014-08-04 Thread Jon via Digitalmars-d-learn

On Monday, 4 August 2014 at 21:10:46 UTC, safety0ff wrote:
Don't forget to call rt_init: 
http://dlang.org/phobos/core_runtime.html#.rt_init


Where/when should I call this?


Re: Haskell calling D code through the FFI

2014-08-04 Thread safety0ff via Digitalmars-d-learn

On Monday, 4 August 2014 at 21:14:17 UTC, Jon wrote:

On Monday, 4 August 2014 at 21:10:46 UTC, safety0ff wrote:
Don't forget to call rt_init: 
http://dlang.org/phobos/core_runtime.html#.rt_init


Where/when should I call this?


Before calling any D functions, but usually it's simplest to call 
it early in main.


It initializes the GC and notifies the D runtime of its existence.
For simple D functions you might get away without calling it.


Re: Haskell calling D code through the FFI

2014-08-04 Thread Jon via Digitalmars-d-learn
I get Error: core.runtime.rt_init is private.  And Error: 
core.runtime.init is not accessible.


On Monday, 4 August 2014 at 21:22:37 UTC, safety0ff wrote:

On Monday, 4 August 2014 at 21:14:17 UTC, Jon wrote:

On Monday, 4 August 2014 at 21:10:46 UTC, safety0ff wrote:
Don't forget to call rt_init: 
http://dlang.org/phobos/core_runtime.html#.rt_init


Where/when should I call this?


Before calling any D functions, but usually it's simplest to 
call it early in main.


It initializes the GC and notifies the D runtime of its 
existence.

For simple D functions you might get away without calling it.




Re: Haskell calling D code through the FFI

2014-08-04 Thread safety0ff via Digitalmars-d-learn

On Monday, 4 August 2014 at 21:35:21 UTC, Jon wrote:
I get Error: core.runtime.rt_init is private.  And Error: 
core.runtime.init is not accessible.




I would add them to the header and Haskell wrapper 
(FunctionsInD.h and ToD.hs.)

The signatures are:
int rt_init();
int rt_term();

When it is linked it will find the symbols in druntime.


Re: Haskell calling D code through the FFI

2014-08-04 Thread Jon via Digitalmars-d-learn

Yes, thank you.  That is exactly what I did.

On Monday, 4 August 2014 at 21:48:40 UTC, safety0ff wrote:

On Monday, 4 August 2014 at 21:35:21 UTC, Jon wrote:
I get Error: core.runtime.rt_init is private.  And Error: 
core.runtime.init is not accessible.




I would add them to the header and Haskell wrapper 
(FunctionsInD.h and ToD.hs.)

The signatures are:
int rt_init();
int rt_term();

When it is linked it will find the symbols in druntime.




Re: Haskell calling D code through the FFI

2014-08-04 Thread Jon via Digitalmars-d-learn
As a note, I can interact with strings as expected, but working 
with structs looks like it will take a little bit of work.


On Monday, 4 August 2014 at 22:17:36 UTC, Jon wrote:

Yes, thank you.  That is exactly what I did.

On Monday, 4 August 2014 at 21:48:40 UTC, safety0ff wrote:

On Monday, 4 August 2014 at 21:35:21 UTC, Jon wrote:
I get Error: core.runtime.rt_init is private.  And Error: 
core.runtime.init is not accessible.




I would add them to the header and Haskell wrapper 
(FunctionsInD.h and ToD.hs.)

The signatures are:
int rt_init();
int rt_term();

When it is linked it will find the symbols in druntime.