Thread overview
Calling D functions from C
Jun 10, 2005
D. Trebbien
Jun 10, 2005
D. Trebbien
June 10, 2005
I know that it is possible to call C functions from D, but is it possible to call D functions from C? What steps would I need to take to allow for this?


June 10, 2005
"D. Trebbien" <D._member@pathlink.com> wrote in message news:d8atov$2v54$1@digitaldaemon.com...
>I know that it is possible to call C functions from D, but is it possible to
> call D functions from C? What steps would I need to take to allow for this?

Since C doesn't know about D, you can't call D functions from C.  The calling conventions are incompatible.

However, you can use the extern(C) function linkage in D to make a function C-compatible:

extern(C) export int something()
{
    // blah
    return 10;
}

The problem is that it's not just this simple.  D is garbage collected, something that C doesn't understand.  If you create some kind of GC'ed object on the heap with 'new' in your D function, and return it without storing the pointer to that memory in the D library, it could be garbage collected without the C code knowing about it.  You must keep the pointer to the memory allocated by the D function in the D library.  The alternative is to have the C code that calls the function allocate the memory for the function.

Unfortunately, the "Interfacing to C" part of the D website seems to have disappeared.  That page had a lot more info on this.


June 10, 2005
Jarrett Billingsley wrote:

> The problem is that it's not just this simple.  D is garbage collected, something that C doesn't understand.  If you create some kind of GC'ed object on the heap with 'new' in your D function, and return it without storing the pointer to that memory in the D library, it could be garbage collected without the C code knowing about it.  You must keep the pointer to the memory allocated by the D function in the D library.  The alternative is to have the C code that calls the function allocate the memory for the function.

You also need to do some C tricks, if you want to use the
D arrays (with length) and the D objects (implicit pointers)

But that doesn't mean that it isn't doable, or anything:

 C:
====
#include <stdlib.h>

struct Darray
{
  size_t length;
  void   *ptr;
};

extern void hello(struct Darray who);

int main(int argc, char *argv[])
{
  struct Darray str = { 5 , "World" };

  hello(str);

  return EXIT_SUCCESS;
}

 D:
====
import std.stdio;

extern(C) void hello(char[] who)
{
  writefln("Hello, %s!", who);
}

You also need to link with Phobos, just as you would have to
link with "stdc++" if you were using a C++ function from C ?

(recls is one library written in C++, with a C extern API)


Mixing languages like that quickly gets ugly, though...
For instance, unsure what happens if "hello" resizes it

Probably better to use regular lengths/pointers args ?

--anders
June 10, 2005
What about hiding (compiled) D code in a DLL; maybe with extern(C) around the
functions?

In article <d8bntp$sa9$1@digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
>
>Jarrett Billingsley wrote:
>
>> The problem is that it's not just this simple.  D is garbage collected, something that C doesn't understand.  If you create some kind of GC'ed object on the heap with 'new' in your D function, and return it without storing the pointer to that memory in the D library, it could be garbage collected without the C code knowing about it.  You must keep the pointer to the memory allocated by the D function in the D library.  The alternative is to have the C code that calls the function allocate the memory for the function.
>
>You also need to do some C tricks, if you want to use the
>D arrays (with length) and the D objects (implicit pointers)
>
>But that doesn't mean that it isn't doable, or anything:
>
>  C:
>====
>#include <stdlib.h>
>
>struct Darray
>{
>   size_t length;
>   void   *ptr;
>};
>
>extern void hello(struct Darray who);
>
>int main(int argc, char *argv[])
>{
>   struct Darray str = { 5 , "World" };
>
>   hello(str);
>
>   return EXIT_SUCCESS;
>}
>
>  D:
>====
>import std.stdio;
>
>extern(C) void hello(char[] who)
>{
>   writefln("Hello, %s!", who);
>}
>
>You also need to link with Phobos, just as you would have to link with "stdc++" if you were using a C++ function from C ?
>
>(recls is one library written in C++, with a C extern API)
>
>
>Mixing languages like that quickly gets ugly, though...
>For instance, unsure what happens if "hello" resizes it
>
>Probably better to use regular lengths/pointers args ?
>
>--anders