digitalmars.D.learn - cooperation between D and C
- Tiago Gasiba (23/23) Jun 14 2005 Hi all,
- Regan Heath (12/43) Jun 14 2005 Yes, it's possible, in short you specify C linkage for the exported D
-
Stewart Gordon
(9/17)
Jun 15 2005
- Tiago Gasiba (6/6) Jun 15 2005 Hi all,
- Tiago Gasiba (54/54) Jun 15 2005 Hi all,
- Walter (3/3) Jun 15 2005 You have both a main() in the C program, and a main() in the D program. ...
- Tiago Gasiba (56/59) Jun 15 2005 Great!
- Tom S (5/20) Jun 15 2005 You're modifying a local copy of the pointer, not the one that you have
- Regan Heath (30/48) Jun 15 2005 I think it's even worse than that. The variable 'Y' is on the stack of t...
- Walter (4/7) Jun 16 2005 Looks to me like X is not initialized before it is passed to func(), mea...
- Tiago Gasiba (8/8) Jun 15 2005 Hi *,
- Tiago Gasiba (14/14) Jun 17 2005 Hi *,
- Brad Beveridge (8/26) Jun 17 2005 If you are making a library (rather than just a .o), there should be a
- Tiago Gasiba (14/22) Jun 17 2005 Sometimes I confuse the word library with object, i.e. .o files. Sorry.
- Brad Beveridge (12/26) Jun 17 2005 That is a tough problem I think. I wonder if something along the lines
Hi all, I just recently downloaded the D linux compiler dmd and started playing around with it. D programming language is completely new to me but my general impression is that it is great! It allows me to write some routines I've previously implemented in C much faster and without memory leakages. I should say that I'm a PhD student in Germany doing its research in a big company. In this company it is quite usual to use C programming language but, since I'm doing research, I'm free to use the tools I want to achieve my purpose. When integrating developed routines (from me or from other colleges for example) into bigger projects, normally two approaches are normally taken: creating a linux library (put in /usr/lib for example), or an object file (.o) to be included and used directly for compilation, if the proper header files (.h) are present. My question is the following: If I use D to develop software and later on I or someone else needs to integrate the routines into a larger project, how can this be done? I've read something about using C routines in D but, is it possible to do it the other way around? What happens with the memory allocation routines and the garbage collector? If this is possible to be done, can someone please provide me with a simple example such that I can start toying around? Thanks, Tiago Gasiba
Jun 14 2005
Yes, it's possible, in short you specify C linkage for the exported D functions. Yes, the GC causes problems, for example if you pass some memory to the C code, but no longer have a reference in the D code, the GC may collect it. The solution is probably to keep a list of memory in the D code, and explicitly free it from the C code, or to use malloc to obtain the memory, or to avoid doing this alltogether. Have a quick look at the " Calling D code from C" thread in this NG. Also the "Calling D functions from C" thread in the digitalmars.D NG. Regan On Wed, 15 Jun 2005 03:31:09 +0200, Tiago Gasiba <tiago.gasiba gmail.com> wrote:Hi all, I just recently downloaded the D linux compiler dmd and started playing around with it. D programming language is completely new to me but my general impression is that it is great! It allows me to write some routines I've previously implemented in C much faster and without memory leakages. I should say that I'm a PhD student in Germany doing its research in a big company. In this company it is quite usual to use C programming language but, since I'm doing research, I'm free to use the tools I want to achieve my purpose. When integrating developed routines (from me or from other colleges for example) into bigger projects, normally two approaches are normally taken: creating a linux library (put in /usr/lib for example), or an object file (.o) to be included and used directly for compilation, if the proper header files (.h) are present. My question is the following: If I use D to develop software and later on I or someone else needs to integrate the routines into a larger project, how can this be done? I've read something about using C routines in D but, is it possible to do it the other way around? What happens with the memory allocation routines and the garbage collector? If this is possible to be done, can someone please provide me with a simple example such that I can start toying around? Thanks, Tiago Gasiba
Jun 14 2005
Regan Heath wrote:Yes, it's possible, in short you specify C linkage for the exported D functions. Yes, the GC causes problems, for example if you pass some memory to the C code, but no longer have a reference in the D code, the GC may collect it. The solution is probably to keep a list of memory in the D code, and explicitly free it from the C code, or to use malloc to obtain the memory, or to avoid doing this alltogether.<snip> Yes, keeping a pointer on the D side works at the moment, but it might not work once a copying GC is out. http://www.digitalmars.com/drn-bin/wwwnews?D/26273 Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 15 2005
Hi all, Where can I get the dstub.d and cstub.c in order to compile D libraries in C? Googling around I could find nothing, and the links given in the thread: www.digitalmars.com/d/archives/ digitalmars/D/learn/630.html do not exist anymore... Thanks!
Jun 15 2005
Hi all, What am I doing wrong in the following code? The idea is to try to pass some values (through a variable) from a function in D into a function in C. The code compiles w/o problems, but does not execute properly - its gets a Segmentation fault. ---------------- (SOURCE) ---------------- -------- Makefile -------- C = gcc D = dmd LIB_OPTS_D = -c -w -g LIB_OPTS_C = -c -Wall -g OPTS_C = -Wall -g all: teste teste: teste.o libd.o $(C) $(OPTS_C) -o teste teste.o libd.o -lphobos -lpthread -lm teste.o: teste.c $(C) $(LIB_OPTS_C) teste.c libd.o: libd.d $(D) $(LIB_OPTS_D) libd.d clean: $(RM) teste $(RM) *.o -------- teste.c -------- #include <stdio.h> #include <stdlib.h> int func2( int * ); int main( int argc, char **argv ){ int *X, i, n; n = func(X); for( i=0; i<n; i++ ) printf("%d\n",X[i]); return 0; } -------- libd.d -------- module libd; const int LEN = 2; extern (C) int func( int *X ){ printf("func - 1\n"); int [] Y; printf("func - 2\n"); Y.length=LEN; printf("func - 3\n"); Y[] = 4; printf("func - 4\n"); X = Y; printf("func - 5\n"); return LEN; } int main( char [][]argv ){ return 0; } ---------------- (END) ---------------- Tiago
Jun 15 2005
You have both a main() in the C program, and a main() in the D program. This will prevent the D startup code from being executed - see the code in phobos/internal/dmain2.d.
Jun 15 2005
Walter wrote:You have both a main() in the C program, and a main() in the D program. This will prevent the D startup code from being executed - see the code in phobos/internal/dmain2.d.Great! I have done some changes (shown later in the email), and now the code compiles and does not give any segmentation fault. The solution I have found is pretty ugly, but it works. However, the C function does not get the correct values from D! I get the following result, by executing the program: gasiba linux:~/D/D in C> ./teste Entering D... func - 1 func - 2 func - 3 func - 4 func - 5 4 4 Leaving D... 134566464 134566644 ---------------- (CHANGED FILES) ---------------- -------- teste.c -------- #include <stdio.h> #include <stdlib.h> int func( int * ); int main2( void ){ int *X, i, n; n = func(X); for( i=0; i<n; i++ ) printf("%d\n",X[i]); return 0; } -------- libd.d -------- module libd; const int LEN = 2; extern (C) int func( int *X ){ printf("Entering D...\n"); printf("func - 1\n"); int [] Y; printf("func - 2\n"); Y.length=LEN; printf("func - 3\n"); Y[] = 4; printf("func - 4\n"); X = Y; printf("func - 5\n"); for( int i=0; i<Y.length; i++ ) printf("%d\n",X[i]); printf("Leaving D...\n"); return LEN; } extern (C) int main2(); int main( char [][]argv ){ return main2(); } ---------------- (END) ---------------- Tiago
Jun 15 2005
Tiago Gasiba wrote:Great! I have done some changes (shown later in the email), and now the code compiles and does not give any segmentation fault. The solution I have found is pretty ugly, but it works. However, the C function does not get the correct values from D!extern (C) int func( int *X ){ printf("Entering D...\n"); printf("func - 1\n"); int [] Y; printf("func - 2\n"); Y.length=LEN; printf("func - 3\n"); Y[] = 4; printf("func - 4\n"); X = Y;You're modifying a local copy of the pointer, not the one that you have in your C function. -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 15 2005
On Thu, 16 Jun 2005 00:15:34 +0200, Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:Tiago Gasiba wrote:I think it's even worse than that. The variable 'Y' is on the stack of the function 'func' and can thus be collected/destroyed after the function has returned. Try: -------- teste.c -------- #include <stdio.h> #include <stdlib.h> int func( int ** ); int main2( void ){ int *X, i, n; n = func(&X); for( i=0; i<n; i++ ) printf("%d\n",X[i]); return 0; } -------- libd.d -------- module libd; const int LEN = 2; int[LEN] Y; extern(C) int func(int **X) { Y[] = 4; *X = Y.ptr; } extern (C) int main2(); int main( char [][]argv ){ return main2(); } ReganGreat! I have done some changes (shown later in the email), and now the code compiles and does not give any segmentation fault. The solution I have found is pretty ugly, but it works. However, the C function does not get the correct values from D!extern (C) int func( int *X ){ printf("Entering D...\n"); printf("func - 1\n"); int [] Y; printf("func - 2\n"); Y.length=LEN; printf("func - 3\n"); Y[] = 4; printf("func - 4\n"); X = Y;You're modifying a local copy of the pointer, not the one that you have in your C function.
Jun 15 2005
"Tiago Gasiba" <tiago.gasiba gmail.com> wrote in message news:d8q89d$u0g$1 digitaldaemon.com...int main2( void ){ int *X, i, n; n = func(X);Looks to me like X is not initialized before it is passed to func(), meaning that garbage is passed.
Jun 16 2005
Hi *, Sorry, small mistake with copy-paste - the prototype of the D function (in the file teste.c) is obviously: int func( int * ); and not func2 as in my previous post. Still, the question remains, where is the bug? :) Thanks, Tiago
Jun 15 2005
Hi *, Thanks you all for the help. I have successfully written and tested a D routine running in a C project. I have written a small tutorial, which you can access through my webpage http://www.gasiba.de under the link "D". Since I'm not a D-guru (in fact I'm a complete novice), please feel free to comment on what I have written. The next question which I would like to ask is, how can I integrate the D startup code, ie gc_init() and others (from dmain2.d), into the C startup code just by linkage. I know the entry point to C is the _start() routine which then calls main(). How can I include some code after the _start(), but before main() such that I'm not required to explicitly call gc_init() in my C project? Thanks, Tiago
Jun 17 2005
Tiago Gasiba wrote:Hi *, Thanks you all for the help. I have successfully written and tested a D routine running in a C project. I have written a small tutorial, which you can access through my webpage http://www.gasiba.de under the link "D". Since I'm not a D-guru (in fact I'm a complete novice), please feel free to comment on what I have written. The next question which I would like to ask is, how can I integrate the D startup code, ie gc_init() and others (from dmain2.d), into the C startup code just by linkage. I know the entry point to C is the _start() routine which then calls main(). How can I include some code after the _start(), but before main() such that I'm not required to explicitly call gc_init() in my C project? Thanks, TiagoIf you are making a library (rather than just a .o), there should be a special library init function that automatically gets called upon library load - I'm not sure what this is, but it is standard for all .so files. If you're just making .o files I don't know - I'd suggest having a single "d_init()" function that gets called. Brad
Jun 17 2005
Brad Beveridge wrote:If you are making a library (rather than just a .o), there should be a special library init function that automatically gets called upon library load - I'm not sure what this is, but it is standard for all .so files. If you're just making .o files I don't know - I'd suggest having a single "d_init()" function that gets called. BradSometimes I confuse the word library with object, i.e. .o files. Sorry. Yes, for now, I'm only interested in generating .o files from D and linking them to a C project. What I would like to avoid is to manually call d_init() in the main() function - this should be done somehow automatically when linking with the D objects. To avoid linker errors in case I decide to use several D .o files, the changes would have to be shifted to, say libphobos; am I right? A simple solution would be to quit the idea of having main() in C and rename it to C_main() for example. Then, a properly designed main() function from D would call C_main(). BUT, this introduces changes to the C project that I'm trying to avoid. BR, Tiago
Jun 17 2005
Tiago Gasiba wrote:Sometimes I confuse the word library with object, i.e. .o files. Sorry. Yes, for now, I'm only interested in generating .o files from D and linking them to a C project. What I would like to avoid is to manually call d_init() in the main() function - this should be done somehow automatically when linking with the D objects. To avoid linker errors in case I decide to use several D .o files, the changes would have to be shifted to, say libphobos; am I right? A simple solution would be to quit the idea of having main() in C and rename it to C_main() for example. Then, a properly designed main() function from D would call C_main(). BUT, this introduces changes to the C project that I'm trying to avoid. BR, TiagoThat is a tough problem I think. I wonder if something along the lines of the following will work: 1) Create a CPP file that has a static class instance, that classes constructor sets up D 2) Link the CPP .o file and D's .o files to the original C project I've seen a similar trick when using dlopen to load dynamic libraries. So if the above works & the CPP static instance correctly sets up D, then there must be some special "run me first" function for .o files, which you could then look at and generate in a less convoluted fashion. Good luck - sounds like you may need it :) Brad
Jun 17 2005