www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using D libs in C

reply GreatEmerald <pastas4 gmail.com> writes:
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
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.exe
 add(4, 5) = 9

Jan 16 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
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
next sibling parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 01/16/2011 05:04 PM, Ellery Newcomer wrote:
 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

hmm. take out the __gshared int, and add -lib to the dmd command, and it does work..
Jan 16 2011
prev sibling parent GreatEmerald <pastas4 gmail.com> writes:
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
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
prev sibling parent reply Trass3r <un known.com> writes:
Also make sure you use globals properly if you use them (shared,  
__gshared, etc.)
Jan 17 2011
next sibling parent reply GreatEmerald <pastas4 gmail.com> writes:
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
parent GreatEmerald <pastas4 gmail.com> writes:
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
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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