www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Ease of calling C code from D

reply "Atila Neves" <atila.neves gmail.com> writes:
One of D's marketed advantages it its compatibility with C. The C 
standard library is even included! However, after having played 
around with this quite a bit last week trying to call legacy C 
code from D, the one thing that put me off and made me think that 
C++ is better for this for my team is the C preprocessor. 
Unfortunately a lot of C code has macros that call macros that 
call other macros, and the only way to properly get around it is 
to hand-translate them one by one.

There is htod but it's Windows only. I tried running it with 
Wine, it didn't work right off the bat and if I had to go check 
out why it didn't work I wasn't going to convince anyone at work 
so I didn't bother. Also, from what I read here on the site I'm 
sure it'd choke on the macros as well.

I know that having a fully-featured C preprocessor in a D 
compiler is a bad idea for several reasons, but in C++ it's 
#include "cheader.h" and, assuming one sets all the revelant -I 
flags to the compiler, that's that. That really is a massively 
important feature (with its downsides, I know).

For popular C libraries there's Deimos (and even then _somebody_ 
has to go to the work and make sure it compiles), but for legacy 
code...

I guess my point is I'm glad I can call C code from D if I really 
have to, but that I'd also think about it twice given the 
interface issues. Another problem I had was the silly C code 
taking char* instead of const char*. Passing in D strings was 
"fun".

Atila
Jan 28 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 28 January 2014 at 20:10:00 UTC, Atila Neves wrote:
 There is htod but it's Windows only.
Did you see Jacob's dstep too? https://github.com/jacob-carlborg/dstep I haven't actually used it myself* but it will surely do a better job than the old htod! * I'm often really lazy with my calling of C code... I translate as little as possible, sometimes just using void* arguments instead of structs... when possible, of course.
Jan 28 2014
next sibling parent reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Tuesday, 28 January 2014 at 20:12:35 UTC, Adam D. Ruppe wrote:
 On Tuesday, 28 January 2014 at 20:10:00 UTC, Atila Neves wrote:
 There is htod but it's Windows only.
Did you see Jacob's dstep too? https://github.com/jacob-carlborg/dstep I haven't actually used it myself* but it will surely do a better job than the old htod! * I'm often really lazy with my calling of C code... I translate as little as possible, sometimes just using void* arguments instead of structs... when possible, of course.
I used dstep to generate a D interface to FFTW (Fastest Fourier-Transform in the West). The header for FFTW includes a massive 100 line (or thereabouts) macro, that basically generates all the function signatures. I ran dstep on fftw3.h and although I have only tested the result a little, thus far it appears to have done a great job! Craig
Jan 28 2014
parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 28 January 2014 at 20:55:15 UTC, Craig Dillabaugh 
wrote:
 I used dstep to generate a D interface to FFTW (Fastest 
 Fourier-Transform in the West). The header for FFTW includes a 
 massive 100 line (or thereabouts) macro, that basically 
 generates all the function signatures.

 I ran dstep on fftw3.h and although I have only tested the 
 result a little, thus far it appears to have done a great job!

 Craig
Right now it will simply expand all macros before conversion. If that is OK, its macro handling capabilities are pretty much equal to clang :)
Jan 28 2014
prev sibling parent reply "Atila Neves" <atila.neves gmail.com> writes:
 Did you see Jacob's dstep too?
I think I read about it here in the forum at some point and somehow forgot about it. I'll definitely give it a go. I also forgot to say that UFCS was pretty cool when dealing with C functions that take a pointer to a struct. Declaring it as ref in D worked too, which I was surprised about, i.e. //C header void doStuff(mystruct *foo, ...); //D file extern(C) void doStuff(ref mystruct, ...); mystruct.doStuff(...); Obviously "extern(C) void doStuff(mystruct*, ...);" also works but it's nice not to have to explicitly take the address of a struct to use it. Atila On Tuesday, 28 January 2014 at 20:12:35 UTC, Adam D. Ruppe wrote:
 On Tuesday, 28 January 2014 at 20:10:00 UTC, Atila Neves wrote:
 There is htod but it's Windows only.
Did you see Jacob's dstep too? https://github.com/jacob-carlborg/dstep I haven't actually used it myself* but it will surely do a better job than the old htod! * I'm often really lazy with my calling of C code... I translate as little as possible, sometimes just using void* arguments instead of structs... when possible, of course.
Jan 28 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 28 January 2014 at 22:11:29 UTC, Atila Neves wrote:
 Did you see Jacob's dstep too?
I think I read about it here in the forum at some point and somehow forgot about it. I'll definitely give it a go.
There is a dstep package in Arch Linux [community] ;)
Jan 28 2014
next sibling parent reply "Atila Neves" <atila.neves gmail.com> writes:
On Tuesday, 28 January 2014 at 22:16:59 UTC, Dicebot wrote:
 On Tuesday, 28 January 2014 at 22:11:29 UTC, Atila Neves wrote:
 Did you see Jacob's dstep too?
I think I read about it here in the forum at some point and somehow forgot about it. I'll definitely give it a go.
There is a dstep package in Arch Linux [community] ;)
Well, then I just _had_ to try it immediately ;). Nice output on some toy stuff I had, but as the github README.md says itself, no preprocessor magic and as far as I can tell no way to specify -I flags so it finds the other headers that get included from the original header. Nice tool, but nowhere near as easy as including the header from C++. I know it's even harder to call C code from other languages (*cough* JNI *cough*), but it's still not automagical from D. It is in C++ (well, assuming the header in question has the appropriate #ifdef'ed extern "C", and even if not it can be done before the #include). I wish I could use D for my use case, but I couldn't responsibly recommend it. Oh well. One of these days I'll figure out how to write D for a living :) Atila
Jan 28 2014
parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 28 January 2014 at 22:33:26 UTC, Atila Neves wrote:
 as far as I can tell no way to specify -I
 flags so it finds the other headers that get included from the
 original header.
Any normal clang flags can be supplied after input file path, including -I (no pun intended)
Jan 28 2014
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/28/14, Dicebot <public dicebot.lv> wrote:
 There is a dstep package in Arch Linux [community] ;)
I was trying out Manjaro recently (yeah I'm a Mint-spoiled n00b) and saw that all D-related packages were packaged by.. Dicebot. :p Thanks!
Jan 29 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 29 January 2014 at 21:16:26 UTC, Andrej Mitrovic 
wrote:
 On 1/28/14, Dicebot <public dicebot.lv> wrote:
 There is a dstep package in Arch Linux [community] ;)
I was trying out Manjaro recently (yeah I'm a Mint-spoiled n00b) and saw that all D-related packages were packaged by.. Dicebot. :p Thanks!
Accepting PRs https://github.com/Dicebot/Arch-PKGBUILDs ;)
Jan 30 2014
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/30/14, Dicebot <public dicebot.lv> wrote:
 Accepting PRs https://github.com/Dicebot/Arch-PKGBUILDs ;)
Noted!
Jan 30 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Atila Neves:

 Another problem I had was the silly C code taking char* instead 
 of const char*. Passing in D strings was "fun".
I don't remember why std.string.toStringz returns a immutable(char)* instead of a char* if you give it a char[]. Bye, bearophile
Jan 28 2014
prev sibling parent "w0rp" <devw0rp gmail.com> writes:
I think initially getting C libraries to work in D has some 
hurdles C++ does not. D doesn't support C's pre-processor macros 
to stop people from using them in D code, compile-time execution 
of D code and templates are more powerful and easier to verify. D 
doesn't use null-terminated strings, character arrays and slices 
are often more efficient and easier to use. The tradeoff for 
these things is that you have to re-write some parts of C 
libraries in D (macros) and translate between differences in how 
D and C do things (toStringZ, etc.).

I think the big payoff comes when you start being able to turn 
struct with pointer + length into a D memory slice without 
copying all the data, when you can determine which functions are 
 system and  safe so you can make it easier to track down 
problems, when you can use scope(exit) and friends to make manual 
resource control less of a headache. I think it's these kinds of 
advantages that typically make me want to try using a library in 
D instead of C++.
Jan 29 2014