digitalmars.D.learn - Using D libs in C
- GreatEmerald (5/5) Jan 16 2011 Is it possible to write a static library in D and then use it in a progr...
- Andrej Mitrovic (18/19) Jan 16 2011 Of course!
- Andrej Mitrovic (5/5) Jan 16 2011 The problem (on Windows), is that the static lib is in the OMF format,
- Ellery Newcomer (3/8) Jan 16 2011 http://www.digitalmars.com/d/archives/digitalmars/D/learn/d_and_c_21526....
- Ellery Newcomer (3/12) Jan 16 2011 hmm. take out the __gshared int, and add -lib to the dmd command, and it...
- Andrej Mitrovic (5/5) Jan 16 2011 I've just realized I didn't even prototype the function in the C
- GreatEmerald (6/6) Jan 17 2011 Ah, I see, thanks! I'll try that.
- Andrej Mitrovic (4/14) Jan 17 2011 There is no dedicated tool that can do it alone, but I think I've just
- Trass3r (2/2) Jan 17 2011 Also make sure you use globals properly if you use them (shared,
- GreatEmerald (19/19) Jan 18 2011 All right, it worked, when the D side is this:
- Andrej Mitrovic (5/24) Jan 19 2011 That's odd. stdio publicly imports std.c.stdio which publicly imports
- GreatEmerald (17/17) Jan 19 2011 Hmm, not being able to use D function kinda defeats the purpose of using...
- GreatEmerald (12/12) Feb 06 2011 All right, found out how to make it compile. There are two ways:
- GreatEmerald (21/21) Feb 06 2011 Hmm, no, it won't work right on Linux for some reason. This is the outpu...
- spir (15/36) Feb 07 2011 Take my words with much doubt, I've few exp in that.
- GreatEmerald (27/27) Feb 07 2011 Everything is right from what I can tell. This is the code I use for the...
- Andrej Mitrovic (4/7) Feb 07 2011 Check the sc.ini file in dmd/windows/bin, make sure it has at least
- Steven Schveighoffer (12/42) Feb 07 2011 The issue is that you are not calling the D runtime initialization code....
- GreatEmerald (6/6) Feb 07 2011 OK, well this is interesting... I managed to compile it but it's quite o...
- spir (10/14) Feb 07 2011 That's it, I guess; you always need a main(), even if empty {}, somewher...
- Steven Schveighoffer (4/37) Feb 07 2011 deh == d exception handling (or handler, not sure) ;)
- spir (13/51) Feb 07 2011 Are you sure of that? I get exactly the same kind of linker error when
- Steven Schveighoffer (5/60) Feb 07 2011 Hm... it looks like _deh_beg and _deh_end is something defined by the
- Jacob Carlborg (4/69) Feb 08 2011 The compiler puts this in the binary.
- Dainius (GreatEmerald) (29/29) Mar 20 2011 Now I'm trying to do something more complicated, and it seems that while
- Dainius (GreatEmerald) (8/8) Mar 22 2011 I've tried compiling the same on Linux and the program still crashes
- Daniel Green (7/15) Mar 22 2011 The D runtime needs to be initialized. Call rt_init before using your
- Dainius (GreatEmerald) (62/62) Mar 23 2011 Ooh, thanks, it works! Though linking in Linux is still quite odd. So
- Daniel Green (14/20) Mar 23 2011 The weird linking with Linux appears to be caused by DMD requiring
- Dainius (GreatEmerald) (9/9) Mar 24 2011 Ah, including pthread indeed works, but now I've run into another
- Jesse Phillips (2/11) Mar 24 2011 Assuming it isn't Production Critical, use -m64 flag in DMD. You shouldn...
- Dainius (GreatEmerald) (10/10) Mar 24 2011 Hmm... Spent a few hours trying to figure out how to update GCC and
- Dainius (GreatEmerald) (3/3) Mar 25 2011 Oh, I found the problem... It's just me forgetting that my library has
- Dainius (GreatEmerald) (4/4) Mar 27 2011 OK, now I have a question about passing variables. In D, I have a
- bearophile (6/10) Mar 27 2011 To use a D data structure from C you need first of all to know what exac...
- Dainius (GreatEmerald) (12/12) Mar 27 2011 Well, the situation is like this: D creates a list of names of files
- bearophile (4/16) Mar 27 2011 So?
- Jesse Phillips (3/15) Mar 27 2011 If you want to pass an array of file names to C, you must pass it as a c...
- Dainius (GreatEmerald) (4/4) Mar 27 2011 Hmm, if I was to do it from C, I would have to deal with all the
- Dainius (GreatEmerald) (16/16) Mar 29 2011 All right, I solved that part of the problem by creating a linked
- Dainius (GreatEmerald) (8/8) Mar 29 2011 Oh, never mind. About sending strings, I got it working, I just had to
- Dainius (GreatEmerald) (9/9) Apr 15 2011 All right, found something really odd today, might be a bug. If in C I
- Andrej Mitrovic (5/5) Apr 15 2011 AFAIK 'int' in D is always a 32-bit value. But in C, 'int' could be
- Dainius (GreatEmerald) (4/4) Apr 15 2011 They both return 4, and both short and int16_t return 2.
- Jacob Carlborg (5/17) Feb 07 2011 I would recommend always linking with dmd, then you want need to link
Is it possible to write a static library in D and then use it in a program written in C? I've found instructions about using DLLs here on the website, but there is no mention about using static libraries instead. Also, is it possible to use the same method on Linux, just with .a files instead? Or .so for that matter?
Jan 16 2011
Of course! dstatic.d: module dstatic; extern(C): int add(int x, int y) { return x + y; } Then compile with: dmd -lib dstatic.d driver.c: #include "stdio.h" int main() { printf("add(4, 5) = %d", add(4, 5)); } dmc driver.c dstatic.lib driver.exeadd(4, 5) = 9
Jan 16 2011
The problem (on Windows), is that the static lib is in the OMF format, and modern tools like VC or MinGW won't be able to read those, because they use COFF instead. So you would have to convert from OMF to COFF. But on Linux I think DMD uses the standard Linux object file format, so I don't think there's issues there. (AFAIK).
Jan 16 2011
On 01/16/2011 03:34 PM, Andrej Mitrovic wrote:The problem (on Windows), is that the static lib is in the OMF format, and modern tools like VC or MinGW won't be able to read those, because they use COFF instead. So you would have to convert from OMF to COFF. But on Linux I think DMD uses the standard Linux object file format, so I don't think there's issues there. (AFAIK).http://www.digitalmars.com/d/archives/digitalmars/D/learn/d_and_c_21526.html it didn't work the last time I tried it
Jan 16 2011
On 01/16/2011 05:04 PM, Ellery Newcomer wrote:On 01/16/2011 03:34 PM, Andrej Mitrovic wrote:hmm. take out the __gshared int, and add -lib to the dmd command, and it does work..The problem (on Windows), is that the static lib is in the OMF format, and modern tools like VC or MinGW won't be able to read those, because they use COFF instead. So you would have to convert from OMF to COFF. But on Linux I think DMD uses the standard Linux object file format, so I don't think there's issues there. (AFAIK).http://www.digitalmars.com/d/archives/digitalmars/D/learn/d_and_c_21526.html it didn't work the last time I tried it
Jan 16 2011
I've just realized I didn't even prototype the function in the C module. DMC doesn't warn about this, it seems. Not even with the -A (ANSI C) flag. It won't even warn me when I prototype the function and pass doubles instead of ints. Maybe I didn't enable all warnings? (I've used: dmc -wc -v2 -A).
Jan 16 2011
Ah, I see, thanks! I'll try that. While I don't have a problem with using DMC, but others who are willing to join my project might have one... Right now I'm using MinGW, so it would definitely be useful to know how to convert the libraries to the format it understands... Though from the looks of it people are having problems with that... coffimplib only does a COFF->OMF conversion, and not the other way round, right?
Jan 17 2011
On 1/17/11, GreatEmerald <pastas4 gmail.com> wrote:Ah, I see, thanks! I'll try that. While I don't have a problem with using DMC, but others who are willing to join my project might have one... Right now I'm using MinGW, so it would definitely be useful to know how to convert the libraries to the format it understands... Though from the looks of it people are having problems with that... coffimplib only does a COFF->OMF conversion, and not the other way round, right?There is no dedicated tool that can do it alone, but I think I've just figured out a way to do it, and I'll post it in the D general newsgroup.
Jan 17 2011
Also make sure you use globals properly if you use them (shared, __gshared, etc.)
Jan 17 2011
All right, it worked, when the D side is this: module techborg; import std.c.stdio; extern(C): shared int ResultD; int Process(int Value) { printf("You have sent the value: %d\n", Value); ResultD = (Value % 5); return ResultD; } However, if I wanted to use printf() from std.stdio, dmc can't link the library any more and complains about undefined symbols: techborg.lib Warning 140: Library probably needs FIXLIB techborg.lib(techborg) Error 42: Symbol Undefined _D3std5stdio12__ModuleInfoZ Also, what was that solution you found for converting OMF->COFF? I can't seem to find the post you mentioned.
Jan 18 2011
On 1/19/11, GreatEmerald <pastas4 gmail.com> wrote:All right, it worked, when the D side is this: module techborg; import std.c.stdio; extern(C): shared int ResultD; int Process(int Value) { printf("You have sent the value: %d\n", Value); ResultD = (Value % 5); return ResultD; } However, if I wanted to use printf() from std.stdio, dmc can't link the library any more and complains about undefined symbols: techborg.lib Warning 140: Library probably needs FIXLIB techborg.lib(techborg) Error 42: Symbol Undefined _D3std5stdio12__ModuleInfoZ Also, what was that solution you found for converting OMF->COFF? I can't seem to find the post you mentioned.That's odd. stdio publicly imports std.c.stdio which publicly imports core.stdc.stdio, where printf is located. Maybe it's a linker bug.. My post was here, I'm not sure why it's not displayed: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=127079
Jan 19 2011
Hmm, not being able to use D function kinda defeats the purpose of using it in the first place. Ah well, let's see if people know more about this elsewhere. Anyway, I'm trying to compile this under Linux now. DMD works brilliantly and I get techborg.a file. I do this (using Debian x64): $ gcc -m32 bioborg.c techborg.a ...and LD is being silly again. This is the error: techborg.a(techborg.o): In function `no symbol': techborg.d:(.text+0x8): undefined reference to `_Dmodule_ref' techborg.a(techborg.o): In function `_D8techborg7__arrayZ': techborg.d:(.text._D8techborg7__arrayZ+0xe): undefined reference to `_d_array_bounds' techborg.a(techborg.o): In function `_D8techborg8__assertFiZv': techborg.d:(.text._D8techborg8__assertFiZv+0xe): undefined reference to `_d_assertm' techborg.a(techborg.o): In function `_D8techborg15__unittest_failFiZv': techborg.d:(.text._D8techborg15__unittest_failFiZv+0xe): undefined reference to `_d_unittestm' collect2: ld returned 1 exit status Any ideas here?
Jan 19 2011
All right, found out how to make it compile. There are two ways: 1) Using DMD for the D part, DMC for the C part and combining them. This is the batch file I use for that: dmd -c -lib dpart.d dmc cpart.c dpart.lib phobos.lib 2) Using DMD for the D part, DMC for the C part, DMD for combining them again: dmd -c -lib dpart.d dmc -c cpart.c dmd cpart.obj dpart.lib phobos.lib The first method gives me a "FIXLIB" warning but compiles OK, the second is nicely silent, thus I prefer the second one. Plus it should work in Linux as well. I'm going to try that shortly.
Feb 06 2011
Hmm, no, it won't work right on Linux for some reason. This is the output: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/../../../libphobos2.a(deh2_4e7_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 The shell script I'm using to compile it is: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a (Although it appears that you don't need to explicitly link with libphobos2, it does it automatically... and fails with the above error.) Any ideas about what the error means?
Feb 06 2011
On 02/07/2011 07:53 AM, GreatEmerald wrote:Hmm, no, it won't work right on Linux for some reason. This is the output: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/../../../libphobos2.a(deh2_4e7_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 The shell script I'm using to compile it is: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a (Although it appears that you don't need to explicitly link with libphobos2, it does it automatically... and fails with the above error.) Any ideas about what the error means?Take my words with much doubt, I've few exp in that. Are you sure you did use same source under both OSes? "undefined reference to `_deh_end' / `_deh_beg'" (read: "D-begin" / "D-end" I guess, looks like Pascal slang ;-) is nicely output by the linker when your "main" module does not have a main(). (There is a similar error when an imported module has a main(), eg for testing, so that the linker finds 2 of them.) Did you change something before compiling under Linux? Or does this pseudo-error happen only under Linux? Add an empty main() to your top module, and tell us... Denis -- _________________ vita es estrany spir.wikidot.com
Feb 07 2011
Everything is right from what I can tell. This is the code I use for the D part: module dpart; import std.c.stdio; extern(C): shared int ResultD; int Process(int Value) { printf("You have sent the value: %d\n", Value); ResultD = (Value % 5); return ResultD; } And the C part: #include <stdio.h> extern int ResultD; int Process(int Value); int main() { printf("Sending 3...\n"); Process(3); printf("The result is %d\n", ResultD); getchar(); return 0; } This is pretty much the same thing as in the Windows version, just with scanf() omitted. Jacob, in Windows I am required to explicitly tell DMD to compile phobos.lib, but not in Linux. Quite odd.
Feb 07 2011
On 2/7/11, GreatEmerald <pastas4 gmail.com> wrote:in Windows I am required to explicitly tell DMD to compile phobos.lib, but not in Linux. Quite odd.Check the sc.ini file in dmd/windows/bin, make sure it has at least this for the LIB variable: LIB="% P%\..\lib";
Feb 07 2011
On Mon, 07 Feb 2011 10:28:41 -0500, GreatEmerald <pastas4 gmail.com> wrote:Everything is right from what I can tell. This is the code I use for the D part: module dpart; import std.c.stdio; extern(C): shared int ResultD; int Process(int Value) { printf("You have sent the value: %d\n", Value); ResultD = (Value % 5); return ResultD; } And the C part: #include <stdio.h> extern int ResultD; int Process(int Value); int main() { printf("Sending 3...\n"); Process(3); printf("The result is %d\n", ResultD); getchar(); return 0; } This is pretty much the same thing as in the Windows version, just with scanf() omitted. Jacob, in Windows I am required to explicitly tell DMD to compile phobos.lib, but not in Linux. Quite odd.The issue is that you are not calling the D runtime initialization code. This is required in order to get D working properly. See the C main function in druntime here: https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L335 Basically, you are going to have to duplicate the runtime startup code. I'm not sure it will work properly. People typically run main from D and call their C functions from there. This is also certainly an option. The errors you are getting are link errors. I'm guessing that maybe because you aren't calling the d runtime, the linker is opimizing out the deh code early on, but then needs it again later? Not sure. -Steve
Feb 07 2011
OK, well this is interesting... I managed to compile it but it's quite odd. In order to do that, I added a call to main() in my Process() function, and then added an empty main() in the D part before "extern(C)". It seems that there are no conflicts, too. Andrej, that line is there. But it really doesn't matter, it's not like adding one word to the command line is hard.
Feb 07 2011
On 02/07/2011 06:41 PM, GreatEmerald wrote:OK, well this is interesting... I managed to compile it but it's quite odd. In order to do that, I added a call to main() in my Process() function, and then added an empty main() in the D part before "extern(C)". It seems that there are no conflicts, too.That's it, I guess; you always need a main(), even if empty {}, somewhere. I routinely add that in every module (part of my template code), if only for running test code, and comment it out when the module is /actually/ imported. I consider this as a minor design error. Denis -- _________________ vita es estrany spir.wikidot.com
Feb 07 2011
On Mon, 07 Feb 2011 06:42:46 -0500, spir <denis.spir gmail.com> wrote:On 02/07/2011 07:53 AM, GreatEmerald wrote:deh == d exception handling (or handler, not sure) ;) Looks like the module that's failing to link is rt.deh -SteveHmm, no, it won't work right on Linux for some reason. This is the output: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/../../../libphobos2.a(deh2_4e7_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 The shell script I'm using to compile it is: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a (Although it appears that you don't need to explicitly link with libphobos2, it does it automatically... and fails with the above error.) Any ideas about what the error means?Take my words with much doubt, I've few exp in that. Are you sure you did use same source under both OSes? "undefined reference to `_deh_end' / `_deh_beg'"
Feb 07 2011
On 02/07/2011 04:32 PM, Steven Schveighoffer wrote:On Mon, 07 Feb 2011 06:42:46 -0500, spir <denis.spir gmail.com> wrote:Are you sure of that? I get exactly the same kind of linker error when forgetting a fake main(){} (whatver the number of modules). Eg: ... src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh21 DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213 HandlerTable+0x13): undefined reference to `_deh_end' ... repeted n times. Denis -- _________________ vita es estrany spir.wikidot.comOn 02/07/2011 07:53 AM, GreatEmerald wrote:deh == d exception handling (or handler, not sure) ;) Looks like the module that's failing to link is rt.dehHmm, no, it won't work right on Linux for some reason. This is the output: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/../../../libphobos2.a(deh2_4e7_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 The shell script I'm using to compile it is: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a (Although it appears that you don't need to explicitly link with libphobos2, it does it automatically... and fails with the above error.) Any ideas about what the error means?Take my words with much doubt, I've few exp in that. Are you sure you did use same source under both OSes? "undefined reference to `_deh_end' / `_deh_beg'"
Feb 07 2011
On Mon, 07 Feb 2011 13:53:14 -0500, spir <denis.spir gmail.com> wrote:On 02/07/2011 04:32 PM, Steven Schveighoffer wrote:Hm... it looks like _deh_beg and _deh_end is something defined by the compiler? It's used in deh2.d but not defined anywhere in druntime. I'm pretty sure deh stands for d exception handler. -SteveOn Mon, 07 Feb 2011 06:42:46 -0500, spir <denis.spir gmail.com> wrote:Are you sure of that? I get exactly the same kind of linker error when forgetting a fake main(){} (whatver the number of modules). Eg: ... src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh21 DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213 HandlerTable+0x13): undefined reference to `_deh_end' ... repeted n times.On 02/07/2011 07:53 AM, GreatEmerald wrote:deh == d exception handling (or handler, not sure) ;) Looks like the module that's failing to link is rt.dehHmm, no, it won't work right on Linux for some reason. This is the output: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/../../../libphobos2.a(deh2_4e7_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 The shell script I'm using to compile it is: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a (Although it appears that you don't need to explicitly link with libphobos2, it does it automatically... and fails with the above error.) Any ideas about what the error means?Take my words with much doubt, I've few exp in that. Are you sure you did use same source under both OSes? "undefined reference to `_deh_end' / `_deh_beg'"
Feb 07 2011
On 2011-02-07 20:07, Steven Schveighoffer wrote:On Mon, 07 Feb 2011 13:53:14 -0500, spir <denis.spir gmail.com> wrote:The compiler puts this in the binary. -- /Jacob CarlborgOn 02/07/2011 04:32 PM, Steven Schveighoffer wrote:Hm... it looks like _deh_beg and _deh_end is something defined by the compiler? It's used in deh2.d but not defined anywhere in druntime. I'm pretty sure deh stands for d exception handler. -SteveOn Mon, 07 Feb 2011 06:42:46 -0500, spir <denis.spir gmail.com> wrote:Are you sure of that? I get exactly the same kind of linker error when forgetting a fake main(){} (whatver the number of modules). Eg: ... src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' ... repeted n times.On 02/07/2011 07:53 AM, GreatEmerald wrote:deh == d exception handling (or handler, not sure) ;) Looks like the module that's failing to link is rt.dehHmm, no, it won't work right on Linux for some reason. This is the output: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/../../../libphobos2.a(deh2_4e7_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end' src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 The shell script I'm using to compile it is: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a (Although it appears that you don't need to explicitly link with libphobos2, it does it automatically... and fails with the above error.) Any ideas about what the error means?Take my words with much doubt, I've few exp in that. Are you sure you did use same source under both OSes? "undefined reference to `_deh_end' / `_deh_beg'"
Feb 08 2011
Now I'm trying to do something more complicated, and it seems that while importing works (it compiles and links fine), actually using the imported things or pretty much anything that D offers makes the program crash. For instance, in the D part: ------------------- module dpart; import std.stdio; version(linux) { int main() { return 0; } } extern(C): shared int ResultD; int Process(int Value) { writeln("hai"); //<- Hangs here printf("You have sent the value %d to the D library.\n", Value); ResultD = (Value % 5); string a; //Doesn't hang a = "10";//Doesn't hang printf("String %s", a); //<- Hangs here return ResultD; } ------------------- There is no readable error, just your ordinary program crash "report this to Microsoft"... Any idea why it's like that?
Mar 20 2011
I've tried compiling the same on Linux and the program still crashes (with segmentation fault there). No error message or anything. And it doesn't matter if I compile the thing from .obj or from .lib files, I still get the same crashes. So it's a real showtopper for me, since what's the use of having static libraries that compile successfully yet crash every time you attempt to use them?.. Anyone have any ideas about what's happening? Or should I just go ahead and submit this to the bug tracker?
Mar 22 2011
On 3/22/2011 6:46 PM, Dainius (GreatEmerald) wrote:I've tried compiling the same on Linux and the program still crashes (with segmentation fault there). No error message or anything. And it doesn't matter if I compile the thing from .obj or from .lib files, I still get the same crashes. So it's a real showtopper for me, since what's the use of having static libraries that compile successfully yet crash every time you attempt to use them?.. Anyone have any ideas about what's happening? Or should I just go ahead and submit this to the bug tracker?The D runtime needs to be initialized. Call rt_init before using your library and rt_term when your done with it. The D runtime replaces main with initialization code and renames the programs main to _Dmain. extern (C) bool rt_init( void delegate( Exception ) dg = null ); extern (C) bool rt_term( void delegate( Exception ) dg = null );
Mar 22 2011
Ooh, thanks, it works! Though linking in Linux is still quite odd. So the final code for my test program is this: ==== cpart.c ==== #include <stdio.h> extern int ResultD; int Process(int Value); int rt_init(); int rt_term(); void LinuxInit(); int main() { int num; rt_init(); //Init D library LinuxInit(); //Code for linking in Linux printf("Enter a number\n"); scanf("%d", &num); Process(num); printf("The result is %d\n", ResultD); getchar(); rt_term(); //Terminate D library } ==== dpart.d ==== module dpart; import std.stdio; version(linux) int main() { return 0; } extern (C) bool rt_init( void delegate( Exception ) dg = null ); extern (C) bool rt_term( void delegate( Exception ) dg = null ); extern(C): shared int ResultD; int Process(int Value) { writeln("You have sent the value: ", Value); ResultD = (Value % 5); return ResultD; } void LinuxInit() { version(linux) main(); } ==== commands to compile ==== On Linux: dmd -m32 -c -lib dpart.d gcc -m32 -c cpart.c dmd -m32 cpart.o dpart.a /usr/lib/libphobos2.a On Windows: dmd -c -lib dpart.d dmc -c cpart.c dmd cpart.obj dpart.lib phobos.lib Or: dmd -lib dpart.d dmc cpart.c dpart.lib C:\D\dmd2\windows\lib\phobos.lib Though I find it quite odd that I need workarounds like those to compile on Linux, but ah well, it works, at least. Also odd that I can't link using GCC on Linux, it gives me a long list of undefined references (it seems that they are all coming from phobos2, it's here if you wish to look through it: http://pastebin.com/cfyMDzDn ). But once again, at least it works now, so thanks a lot!
Mar 23 2011
On 3/23/2011 3:22 AM, Dainius (GreatEmerald) wrote:Though I find it quite odd that I need workarounds like those to compile on Linux, but ah well, it works, at least. Also odd that I can't link using GCC on Linux, it gives me a long list of undefined references (it seems that they are all coming from phobos2, it's here if you wish to look through it: http://pastebin.com/cfyMDzDn ). But once again, at least it works now, so thanks a lot!The weird linking with Linux appears to be caused by DMD requiring symbols for thread local storage. When you declare main, DMD will output those symbols. I don't know of any other way to get those symbols. int function() _main = &main; // Makes DMD output the _tls symbols. Your issue when linking with GCC looks like your missing the pthread library or development files. gcc cpart.o -o cpart -m32 -Xlinker -L/home/venix/dmd2/linux/bin/../lib32 -Xlinker -L/home/venix/dmd2/linux/bin/../lib64 -Xlinker --no-warn-search-mismatch -Xlinker --export-dynamic -lrt dpart.a -lphobos2 **-lpthread** -lm Something a little more cosmetic, would be to have the D library call rt_init and rt_term. That could be automatic with a shared library. With a static library having Library_Init and Library_Quit do it would work.
Mar 23 2011
Ah, including pthread indeed works, but now I've run into another problem related to Linux and architecture. I want to use D for my program that also uses things like SDL and Lua. Earlier when I compiled it, I always did so with 64-bit libraries. But D is so far only in 32-bits, thus when compiling it doesn't accept phobos2. And it also seems that Debian x64 (which I'm using to compile this at the moment) doesn't have 32-bit libs of SDL as well. Plus compiling SDL from source doesn't work either. So how should I proceed with this? Try to get the beta D x64 libraries?
Mar 24 2011
Dainius (GreatEmerald) Wrote:Ah, including pthread indeed works, but now I've run into another problem related to Linux and architecture. I want to use D for my program that also uses things like SDL and Lua. Earlier when I compiled it, I always did so with 64-bit libraries. But D is so far only in 32-bits, thus when compiling it doesn't accept phobos2. And it also seems that Debian x64 (which I'm using to compile this at the moment) doesn't have 32-bit libs of SDL as well. Plus compiling SDL from source doesn't work either. So how should I proceed with this? Try to get the beta D x64 libraries?Assuming it isn't Production Critical, use -m64 flag in DMD. You shouldn't need to "get" the libraries as they come with dmd 2.052. The generated 64 bit might be buggy, but people need to start using it so bugs can be found.
Mar 24 2011
Hmm... Spent a few hours trying to figure out how to update GCC and all to conform to the requirements for 2.0.52, and at seems that it compiles my small test program just fine, but it fails on compiling the main project for some reason. And the linker outputs half-scrambled things. Anyway, here's all the output that shows how I'm trying to build the thing: http://pastebin.com/j7bE76bn It seems that it for some odd reason doesn't want to link the imports, and I don't see why is that, since my small test program works, and it uses basically the same thing...
Mar 24 2011
Oh, I found the problem... It's just me forgetting that my library has to go before phobos to compile it. So right now it works perfectly! Thanks!
Mar 25 2011
OK, now I have a question about passing variables. In D, I have a dynamic array of strings and I want C to get that array. Yet C supports neither dynamic arrays nor strings. So is there a way to accomplish this?
Mar 27 2011
Dainius (GreatEmerald):OK, now I have a question about passing variables. In D, I have a dynamic array of strings and I want C to get that array. Yet C supports neither dynamic arrays nor strings. So is there a way to accomplish this?To use a D data structure from C you need first of all to know what exactly those data structures are. In this case one solution is to create (from D) a dynamic array of char*, then perform a map!toStringz to convert the strings to C strings, and then call the C code with the ptr and length of this dynamic array of pointers. There are other solutions, according to the amount of data you want to copy or according to the amount of C code you want to write to access the D data structures. Bye, bearophile
Mar 27 2011
Well, the situation is like this: D creates a list of names of files that should be loaded by C. C then takes the list, uses it to load the files, then stores both the pointers to the loaded files and the names of the files in an array of structs. Then when C wants to access the files, it asks D about which file to access, which then sends the file name, and C compares the known file names and on finding a match, accesses the file. So that means that the array should be pretty much read-only there, but C needs to know how big the newly created array of structs has to be. As for how long the list of file names will be - it's determined by the configuration, so it will be anywhere from 1 to around 300 or even more.
Mar 27 2011
Dainius (GreatEmerald):Well, the situation is like this: D creates a list of names of files that should be loaded by C. C then takes the list, uses it to load the files, then stores both the pointers to the loaded files and the names of the files in an array of structs. Then when C wants to access the files, it asks D about which file to access, which then sends the file name, and C compares the known file names and on finding a match, accesses the file. So that means that the array should be pretty much read-only there, but C needs to know how big the newly created array of structs has to be. As for how long the list of file names will be - it's determined by the configuration, so it will be anywhere from 1 to around 300 or even more.So? Bye, bearophile
Mar 27 2011
Dainius (GreatEmerald) Wrote:Well, the situation is like this: D creates a list of names of files that should be loaded by C. C then takes the list, uses it to load the files, then stores both the pointers to the loaded files and the names of the files in an array of structs. Then when C wants to access the files, it asks D about which file to access, which then sends the file name, and C compares the known file names and on finding a match, accesses the file. So that means that the array should be pretty much read-only there, but C needs to know how big the newly created array of structs has to be. As for how long the list of file names will be - it's determined by the configuration, so it will be anywhere from 1 to around 300 or even more.If you want to pass an array of file names to C, you must pass it as a char**, accomplished as bearophile has stated. Since your C program is asking D which files to work with next why doesn't it load the file at that time? If the file is processed multiple times, you can still cache the data and just check if it is already cached.
Mar 27 2011
Hmm, if I was to do it from C, I would have to deal with all the allocation, since I don't know how large the array is going to be when it's complete, while D doesn't need to know since it uses dynamic arrays.
Mar 27 2011
All right, I solved that part of the problem by creating a linked list. However, getting the string out of D is still problematic, namely because toStringz() gives me an immutable char*, and I don't seem to be able to pass those, since I can't assign those to immutable variables outside their constructors. Also, if I use this: //D: void GetString() { ReceiveString(toStringz(StringD)); } //C: extern(C) void ReceiveString(char* String) { StringC = String; } DMD gives me "Error: undefined identifier ReceiveString" for some reason.
Mar 29 2011
Oh, never mind. About sending strings, I got it working, I just had to create a function like this in D: immutable(char)* GetString() { return StringD.toStringz(); } As for D not compiling, I had to declare it in D, d'oh :D And that extern is in the wrong place there.
Mar 29 2011
All right, found something really odd today, might be a bug. If in C I have this: int16_t D_getPictureCoordX(int Pool, int Card); And in D I have this: short D_getPictureCoordX(int Pool, int Card); When I call D_getPictureCoord() from C, the parameters are all off, it seems that it receives either a random memory bit or the parameters are not in the same order as they should be. However, this only happens in Linux using 64-bit DMD, on Windows it works just fine.
Apr 15 2011
AFAIK 'int' in D is always a 32-bit value. But in C, 'int' could be 64bit on 64bit platforms. You could try printing sizeof(int) in C and compare that to int.sizeof in D and see if they match. You probably know this, but make sure your exported D function is annotated with extern(C).
Apr 15 2011
They both return 4, and both short and int16_t return 2. Also, I've noticed that if I use a struct (of four ints) instead, the same thing happens, the parameters are not correct. And yes, of course they are extern already.
Apr 15 2011
On 2011-02-07 07:32, GreatEmerald wrote:All right, found out how to make it compile. There are two ways: 1) Using DMD for the D part, DMC for the C part and combining them. This is the batch file I use for that: dmd -c -lib dpart.d dmc cpart.c dpart.lib phobos.lib 2) Using DMD for the D part, DMC for the C part, DMD for combining them again: dmd -c -lib dpart.d dmc -c cpart.c dmd cpart.obj dpart.lib phobos.lib The first method gives me a "FIXLIB" warning but compiles OK, the second is nicely silent, thus I prefer the second one. Plus it should work in Linux as well. I'm going to try that shortly.I would recommend always linking with dmd, then you want need to link any D specifics, like phobos. -- /Jacob Carlborg
Feb 07 2011