Thread overview
Calling D from C - What's the present status?
Jan 19, 2007
hauptmech
Jan 20, 2007
Daniel Keep
Jan 20, 2007
Bill Baxter
Jan 20, 2007
Frits van Bommel
Jan 20, 2007
Kirk McDonald
January 19, 2007
I'd like to maintain an internal (to my company) code library in D but provide customers with a libxxx.a and *.h files so they can use C.

I'd like to provide access to classes and members. My C library code is more or less object oriented (ei pass in a pointer to data as the first arg to a "member" function) so customers can deal with that.

I read the short snippet that said functions attributed as extern(C) can be called... and I vaguely rememeber experimenting a year ago and being able to call class members with a little pointer abuse...

Is there a compiler switch that will generate a nice *.h file?!?

Or perhapse more reasonably; does anyone know of any projects out there geared towards providing C bindings for D libraries in an automated way?

hauptmech





January 20, 2007
hauptmech wrote:
> I'd like to maintain an internal (to my company) code library in D
> but provide customers with a libxxx.a and *.h files so they can use C.
> 
> I'd like to provide access to classes and members. My C library code
> is more or less object oriented (ei pass in a pointer to data as the
> first arg to a "member" function) so customers can deal with that.
> 
> I read the short snippet that said functions attributed as extern(C)
> can be called... and I vaguely rememeber experimenting a year ago and
> being able to call class members with a little pointer abuse...
> 
> Is there a compiler switch that will generate a nice *.h file?!?
> 
> Or perhapse more reasonably; does anyone know of any projects out
> there geared towards providing C bindings for D libraries in an
> automated way?
> 
> hauptmech

AFAIK, there is no automated mechanism for generating .h files -- historically, we've been more worried about calling back to C and C++ than the other way around :)

Here's what I *do* know on the subject:

"extern(C)" lets you use perfectly normal C calling conventions.  So, for example, if you compile this:

extern(C) int add(int a, int b) { return a + b; }

to an object file, and link it into a C program that has the following declaration somewhere:

int add(int, int);

Then it should all work as expected.  The trouble comes in because of D's additional features such as the garbage collector (used by default for all heap allocations), module constructors/destructors, etc.

As for exposing D classes to C, you would have to do what you would normally do with C++: build a "flat api" wrapper around the classes for C to use.

I'm afraid I can't really offer anything more; if you check out the phobos source code (which comes with DMD), it contains the main function used by D programs (which in turn calls the main function defined in your code).  This includes details on how to do things like start up the garbage collector and do initialisation, etc.

Best of luck to you :)

	-- Daniel
January 20, 2007
Daniel Keep wrote:
> hauptmech wrote:
>> I'd like to maintain an internal (to my company) code library in D
>> but provide customers with a libxxx.a and *.h files so they can use C.
>>
>> I'd like to provide access to classes and members. My C library code
>> is more or less object oriented (ei pass in a pointer to data as the
>> first arg to a "member" function) so customers can deal with that.
>>
>> I read the short snippet that said functions attributed as extern(C)
>> can be called... and I vaguely rememeber experimenting a year ago and
>> being able to call class members with a little pointer abuse...
>>
>> Is there a compiler switch that will generate a nice *.h file?!?
>>
>> Or perhapse more reasonably; does anyone know of any projects out
>> there geared towards providing C bindings for D libraries in an
>> automated way?
>>
>> hauptmech
> 
> AFAIK, there is no automated mechanism for generating .h files -- historically, we've been more worried about calling back to C and C++ than the other way around :)
> 
> Here's what I *do* know on the subject:
> 
> "extern(C)" lets you use perfectly normal C calling conventions.  So, for example, if you compile this:
> 
> extern(C) int add(int a, int b) { return a + b; }
> 
> to an object file, and link it into a C program that has the following declaration somewhere:
> 
> int add(int, int);
> 
> Then it should all work as expected.  The trouble comes in because of D's additional features such as the garbage collector (used by default for all heap allocations), module constructors/destructors, etc.
> 
> As for exposing D classes to C, you would have to do what you would normally do with C++: build a "flat api" wrapper around the classes for C to use.
> 
> I'm afraid I can't really offer anything more; if you check out the phobos source code (which comes with DMD), it contains the main function used by D programs (which in turn calls the main function defined in your code).  This includes details on how to do things like start up the garbage collector and do initialisation, etc.
> 
> Best of luck to you :)
> 
>     -- Daniel

Seems like there should be a single handy extern (C) function in phobos to handle that standard startup and shutdown stuff.  I've seen a couple of D programs that do this manually (I think the most recent was one of Kirk's PyD samples).  Is there some reason that stuff can't just be thrown in a single DRuntimeInit / DRuntimeClose pair of functions?
Tango folks?
--bb
January 20, 2007
Bill Baxter wrote:
> Seems like there should be a single handy extern (C) function in phobos to handle that standard startup and shutdown stuff.  I've seen a couple of D programs that do this manually (I think the most recent was one of Kirk's PyD samples).  Is there some reason that stuff can't just be thrown in a single DRuntimeInit / DRuntimeClose pair of functions?

Well, for one thing, the standard wrapper also catches exceptions. That's kind of hard to do with a pair of functions. Other than that, I don't see a problem with it.

> Tango folks?
> --bb
January 20, 2007
Frits van Bommel wrote:
> Bill Baxter wrote:
> 
>> Seems like there should be a single handy extern (C) function in phobos to handle that standard startup and shutdown stuff.  I've seen a couple of D programs that do this manually (I think the most recent was one of Kirk's PyD samples).  Is there some reason that stuff can't just be thrown in a single DRuntimeInit / DRuntimeClose pair of functions?
> 
> 
> Well, for one thing, the standard wrapper also catches exceptions. That's kind of hard to do with a pair of functions. Other than that, I don't see a problem with it.
> 

Each function that is directly exposed to C must ensure that exceptions do not escape from your D code. Pyd does this with a handy function template that translates D exceptions into Python exceptions:
    http://pyd.dsource.org/except_wrapping.html
You will probably have to think of some other way to handle exceptions escaping from D, but something like Pyd's exception_catcher is one solution to consider.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org