
I'm looking for opinions as to the best way to do a C (or C++) foreign interface to GHC haskell code. It looks like there are three options. Greencard has been around for a while, but it looks as if it's more-or-less deprecated now; I don't see many people talking about it anymore. Unless I'm wrong about this (and if I am, please disabuse me of this bias), it doesn't sound like the obvious choice. That leaves me with GHC's FFI and hdirect. I've played around a bit with hdirect in ghc-5.02 and it works. I haven't really looked at the native FFI (beyond reading some manual pages), so I'm not really sure what hdirect provides that the FFI doesn't. From a cursory glance it looks like hdirect's ihc is useful for auto-generating interface files, but it may be over-kill for my smallish project. Any feedback or personal biases are welcomed. Thanks, --Mark

Hi,
GreenCard is still widely used, but doesn't offer any
support for what you're wanting to do.
Is the auto-generation of proxy code around the Haskell
functions you want to export worth your while to get
started with HDirect? Don't know, you may want to try
doing it manually for a couple of the functions (perhaps
by looking at the Haskell code that HDirect generates
for the server/ example) & then decide.
hth
--sigbjorn
----- Original Message -----
From: "Mark Conway Wirt"
To:
I'm looking for opinions as to the best way to do a C (or C++) foreign interface to GHC haskell code.
It looks like there are three options. Greencard has been around for a while, but it looks as if it's more-or-less deprecated now; I don't see many people talking about it anymore. Unless I'm wrong about this (and if I am, please disabuse me of this bias), it doesn't sound like the obvious choice.
That leaves me with GHC's FFI and hdirect. I've played around a bit with hdirect in ghc-5.02 and it works. I haven't really looked at the native FFI (beyond reading some manual pages), so I'm not really sure what hdirect provides that the FFI doesn't. From a cursory glance it looks like hdirect's ihc is useful for auto-generating interface files, but it may be over-kill for my smallish project.
Any feedback or personal biases are welcomed.
Thanks,
--Mark
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Mark Conway Wirt wrote,
I'm looking for opinions as to the best way to do a C (or C++) foreign interface to GHC haskell code.
It looks like there are three options.
I think, there are five options: * H/Direct (you mentioned that already) * GreenCard (ditto) * C->Haskell http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ * hsc2hs (comes with GHC) * Plain FFI Cheers, Manuel

On Sat, Jan 12, 2002 at 01:24:54PM +1100, Manuel M. T. Chakravarty wrote:
Mark Conway Wirt wrote,
I'm looking for opinions as to the best way to do a C (or C++) foreign interface to GHC haskell code.
It looks like there are three options.
I think, there are five options:
* H/Direct (you mentioned that already) * GreenCard (ditto) * C->Haskell http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ * hsc2hs (comes with GHC) * Plain FFI
And what are the pros and cons of each? Presumably you recommend C->Haskell, since you wrote it; what makes it better? (My situation: I want to interface to C code with several rather large structures, so plain FFI is not very attractive. I've started using C->Haskell, but am curious about other people's experiences.) --Dylan Thurston

Dylan Thurston
On Sat, Jan 12, 2002 at 01:24:54PM +1100, Manuel M. T. Chakravarty wrote:
I think, there are five options:
* H/Direct (you mentioned that already) * GreenCard (ditto) * C->Haskell http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ * hsc2hs (comes with GHC) * Plain FFI
And what are the pros and cons of each? Presumably you recommend C->Haskell, since you wrote it; what makes it better?
Since your are asking, here my shamelessly biased opinion ;-) I don't think that it makes much sense coding on the plain FFI unless there are reasons for avoiding an extra tool or the binding is very small. Moreover, GreenCard (with all due respect) is a bit of a legacy. The other three tools clearly benefited from the GreenCard experience, but after all they were developed, because the authors thought that they can improve on GreenCard. This leaves us with H/Direct, C->Haskell, and hsc2hs. I chose the order of listing these three tools on purpose. It is not only the historical order, but enumerates them in order of decreasing complexity. H/Direct is clearly the most powerful of the three. It is an IDL compiler with the ability to process a combination of C header files and matching annotation files as a form of poor man's IDL, whereas C->Haskell and hsc2hs only have one goal: Simplify the development of Haskell bindings to C libraries. I believe in the design philosophy of having a set of small tools that do just one job, but do it well. So, I prefer a specialised tool like C->Haskell and besides, when I initially developed C->Haskell, H/Direct couldn't handle C headers yet. As for a feature comparison, this is what comes to my mind: H/Direct pros: - It can automatically marshal structures. In C->Haskell, you have to do some of this manually. Automating the process is on the todo list. C->Haskell pros: - Given a header file, you write on file which contains the Haskell API and binding hooks that link the Haskell entities to C entities. With H/Direct, you need the annotation file plus usually a Haskell module that redresses the automatically generated interface to what you want to present to the user. - Marshalling is expressed using a marshalling library in plain Haskell, which means it is easy to write special code to handle weird cases. Regarding hsc2hs, it's idea was to be even simpler than C->Haskell. In particular, it is independent of the used C compiler, whereas C->Haskell has to imitate part of what a C compiler does. However, this comes at the expense of IMHO rather messy quoting requirements. Moreover, there is the potential in C->Haskell to provide quite a bit more automation than it implements at the moment. Cheers, Manuel

don't forget one very big pro for hsc2hs, which is that it comes with ghc so you can count on it working. I find it tricky to keep c2hs (and hence gtk+hs) working with the latest ghc. no doubt the situation is getting better, but it is still somewhat of a hassle. I tend to use hsc2hs for 'small' bindings of a few functions, or when i am writing both the c and haskell code, and c2hs to try and wrap premade c libraries. John On Mon, Jan 14, 2002 at 04:45:12PM +1100, Manuel M. T. Chakravarty wrote:
Dylan Thurston
wrote, On Sat, Jan 12, 2002 at 01:24:54PM +1100, Manuel M. T. Chakravarty wrote:
I think, there are five options:
* H/Direct (you mentioned that already) * GreenCard (ditto) * C->Haskell http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ * hsc2hs (comes with GHC) * Plain FFI
And what are the pros and cons of each? Presumably you recommend C->Haskell, since you wrote it; what makes it better?
Since your are asking, here my shamelessly biased opinion ;-)
I don't think that it makes much sense coding on the plain FFI unless there are reasons for avoiding an extra tool or the binding is very small. Moreover, GreenCard (with all due respect) is a bit of a legacy. The other three tools clearly benefited from the GreenCard experience, but after all they were developed, because the authors thought that they can improve on GreenCard. This leaves us with H/Direct, C->Haskell, and hsc2hs.
I chose the order of listing these three tools on purpose. It is not only the historical order, but enumerates them in order of decreasing complexity. H/Direct is clearly the most powerful of the three. It is an IDL compiler with the ability to process a combination of C header files and matching annotation files as a form of poor man's IDL, whereas C->Haskell and hsc2hs only have one goal: Simplify the development of Haskell bindings to C libraries.
I believe in the design philosophy of having a set of small tools that do just one job, but do it well. So, I prefer a specialised tool like C->Haskell and besides, when I initially developed C->Haskell, H/Direct couldn't handle C headers yet. As for a feature comparison, this is what comes to my mind:
H/Direct pros: - It can automatically marshal structures. In C->Haskell, you have to do some of this manually. Automating the process is on the todo list.
C->Haskell pros: - Given a header file, you write on file which contains the Haskell API and binding hooks that link the Haskell entities to C entities. With H/Direct, you need the annotation file plus usually a Haskell module that redresses the automatically generated interface to what you want to present to the user. - Marshalling is expressed using a marshalling library in plain Haskell, which means it is easy to write special code to handle weird cases.
Regarding hsc2hs, it's idea was to be even simpler than C->Haskell. In particular, it is independent of the used C compiler, whereas C->Haskell has to imitate part of what a C compiler does. However, this comes at the expense of IMHO rather messy quoting requirements. Moreover, there is the potential in C->Haskell to provide quite a bit more automation than it implements at the moment.
Cheers, Manuel
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
-- --------------------------------------------------------------------------- John Meacham - California Institute of Technology, Alum. - john@repetae.net ---------------------------------------------------------------------------

John Meacham
don't forget one very big pro for hsc2hs, which is that it comes with ghc so you can count on it working.
True.
I find it tricky to keep c2hs (and hence gtk+hs) working with the latest ghc. no doubt the situation is getting better, but it is still somewhat of a hassle.
The problem with GHC 5.02.1 was a bug in GHC's -M option. Otherwise, I usually make an effort keep the tool up to date. It works with 5.02.2 again, btw. (Though, I admit, I only tested with the CVS version.) Cheers, Manuel

Manuel M. T. Chakravarty wrote: | I don't think that it makes much sense coding on the | plain FFI unless there are reasons for avoiding an | extra tool or the binding is very small. Just my $0.02: I have used the plain FFI for larger projects. The initial reason I did this because my version of H/Direct stopped working after I switched to a newer GHC, and I did not feel like trying to fix it (again), or install a new tool. So, I was forced to use the plain FFI. I found it delightfully simple! To write a correct FFI instance, I think it is absolutely important that you understand completely what is happening under the hood. My experience with H/Direct is that too much is happening, and the things going on are so subtle, so that often I look at the generated code to look if it has done the correct thing. The amount of work involved was not so bad at all. Usually, I find that a small set of ad+hoc combinators (custom written wrappers) will help one out a lot. I have this experience both with static C libraries I want to link to (written and published by other people), and dynamic libraries (being under development by myself). Admittedly not as large as gtk+hs, but still reasonably large. One more note I like to make: Using H/Direct (and no doubt any of the other tools as well), I find that one ends up writing a wrapper module anyway, which gives the library in question a more Haskell-like interface (types, function names, order of arguments, extra polymorphism wrappers, runST-like tricks, etc.) The amount of work involved removing the extra (automatic) layer is about the same as the amount of work trying to make the interface compatible with the automatically generated stuff. /Koen.

Koen Claessen
Manuel M. T. Chakravarty wrote:
| I don't think that it makes much sense coding on the | plain FFI unless there are reasons for avoiding an | extra tool or the binding is very small.
Just my $0.02:
I have used the plain FFI for larger projects. The initial reason I did this because my version of H/Direct stopped working after I switched to a newer GHC, and I did not feel like trying to fix it (again), or install a new tool. So, I was forced to use the plain FFI.
I found it delightfully simple! [..] One more note I like to make: Using H/Direct (and no doubt any of the other tools as well), I find that one ends up writing a wrapper module anyway, which gives the library in question a more Haskell-like interface (types, function names, order of arguments, extra polymorphism wrappers, runST-like tricks, etc.) The amount of work involved removing the extra (automatic) layer is about the same as the amount of work trying to make the interface compatible
I agree completely - except that in C->Haskell (and also hsc2hs) you do *not* have to write that extra layer. Or to be precise, you do it in one go. This was one of the main design goals in C->Haskell. You may know that when I started on Gtk+HS, I used the same approach as you (for similar reasons as you do). After many lines of code, I found that it works nice that way, but there are a couple of things which when automated would save quite same work. So, I automated just these piece, the rest is still just verbatim Haskell code doing the marshalling. Cheers, Manuel

I'd like to say thanks to everyone who responded. At this point, I think I'll try each -- the FFI to get a feel for the low-level goings-on, C->Haskell 'cause it looks interesting, and H/Direct for it's power. After I've tried each, I'll have a better understanding and be able to evaluate each one. Thanks again! --Mark
participants (6)
-
Dylan Thurston
-
John Meacham
-
Koen Claessen
-
Manuel M. T. Chakravarty
-
Mark Conway Wirt
-
Sigbjorn Finne