www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Calling D functions from C

reply D. Trebbien <D._member pathlink.com> writes:
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?
Jun 09 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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.
Jun 09 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
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
Jun 10 2005
parent D. Trebbien <D._member pathlink.com> writes:
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

Jun 10 2005