Saturday, September 10, 2011

Calling a C shared library from D

As I said at the end of my post on C++ vs Fortran, I think D is a better language than C++. My preferred language is Lisp (newLISP for little jobs and Clojure for the heavy stuff). The more I play with D, though, the more I like it.

As good as the language is, there are some obvious problems - the website needs to be redone by a professional web designer, and the available libraries on dsource should be better organized so it's easier to find what you're looking for, dead projects thrown out or put into their own area, and a clear separation between the D1 and D2 projects. Even better would be to give some guidelines to contributors, and suggestions as to critical projects.

Until a few days ago I had been slowly learning D by reading The D Programming Language and porting C functions to D. I then decided that D is definitely worth having in my toolbox when I want a compiled language. To be practical I need to be able to link to C shared libraries.

This is such an important thing that you'd expect there to be a clear, easy-to-follow tutorial hitting you in the face as soon as you go to the website. Not really. It's not difficult at all to do. It's just that the information is scattered all around. I don't see any way that someone who does not have C/C++ experience can figure it out. That's a shame because a very good reason to use D is that you want to use a language that provides you with more than just access to the computer's memory (unlike C) and doesn't require a decade to achieve mediocrity (unlike C++).

So here's a simple example. This site shows how to make a .so using GCC. That's  sufficient for our purposes. I called my shared library libmean.so.

On the D side, here is a file (dlinktoc.d) that calls the C function "mean":


import std.stdio;
extern (C) double mean(double a, double b);

void main() {
double a = 4.7;
double b = 7.6;
auto c = mean(a,b);
writeln("The mean is: ",c);
}

This is a typical D program except that I have included the extern (C) line to tell D that mean is a C function. I saved dlinktoc.d in the same directory as I created libmean.so.

The compiling and linking is similar to what you would do with a C program:


dmd dlinktoc.d -L./libmean.so

Running:

./dlinktoc
The mean is: 6.15

4 comments:

jhuni said...

Why is this on planet clojure?

lmf said...

Don't know. I don't visit Planet Clojure. It may automatically have been added because it says at the top that Clojure is my preferred language for big programming tasks. Just a guess.

Anonymous said...

Because Clojure should have D as the next compile target :)

Who needs javascript when there is NaCl

lmf said...

Because Clojure should have D as the next compile target :)

Then I'd be in heaven! I doubt I'd ever get that lucky.