digitalmars.D - Calling D functions from C
- D. Trebbien (2/2) Jun 09 2005 I know that it is possible to call C functions from D, but is it possibl...
- Jarrett Billingsley (21/25) Jun 09 2005 Since C doesn't know about D, you can't call D functions from C. The
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (33/41) Jun 10 2005 You also need to do some C tricks, if you want to use the
- D. Trebbien (4/45) Jun 10 2005 What about hiding (compiled) D code in a DLL; maybe with extern(C) aroun...
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
"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
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
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