Calling C functions

Steven Schveighoffer schveiguy at yahoo.com
Thu Dec 9 06:57:56 PST 2010


On Thu, 09 Dec 2010 09:37:03 -0500, CrypticMetaphor  
<CrypticMetaphor88 at gmail.com> wrote:

> I found this page that describes how to call c functions from D.
>
> I found this page that describes how:
> http://arsdnet.net/dtips/#cfunc
>
> on that page he uses gcc, and I use dmc, but I get different results.  
> This is what I did
>
> // cfile.c file
> extern int globalFromD;
>
> void functionFromC(int a) {
>     globalFromD = a;
> }
> // end cfile.c
>
> // dfile.d
> extern(C) { // this is needed to make it available from C
>          int globalFromD;
> }
> extern(C) { // also needed when listing the prototypes for your C  
> functions
>          void functionFromC(int);
> }
>
> import std.stdio; // for writefln
>
> int main() {
>          globalFromD = 100;
>          writefln("%d", globalFromD);
>
>          functionFromC(500);
>          writefln("%d", globalFromD);
>
>          return 0;
> }
> // end dfile.d
>
> I compile with:
> dmc -c cfile.c
> And I get  an cfile.obj, which is the object code (.o in gcc).
> Then I compile the D code
> dmd dfile.d cfile.obj
> and I get no errors, so I run it, the result:
> // start result
> C:\DCode\libtest>dfile.exe
> 100
> 100
>
> C:\DCode\libtest>
> // end result
>
> Why is it still 100? It should be 500. I don't think functionFromC( int  
> ) is being called, and I can't really find any other sources that  
> clearly explain how to do this simple stuff, so can anyone explain how  
> to fix it?

I'm guessing that this is a later D2 compiler?  If so, then the default  
storage for globals is in Thread Local Storage (local to each thread).   
This could explain why it doesn't work, because globalFromD is in TLS in  
D-land, but in the normal global space in C-land.  But there is no  
declaration of the global-space version then, so I'm surprised it would  
compile then.

I'm really curious why this doesn't work but does compile.

What version of D compiler are you using?

When using dmd 2.050 on linux I get this error when compiling:

steves at steve-laptop:~/testd$ gcc -c testc.c
steves at steve-laptop:~/testd$ ~/dmd-2.050/linux/bin/dmd testcallc.d testc.o
/usr/bin/ld: globalFromD: TLS definition in testcallc.o section .tbss  
mismatches non-TLS reference in testc.o
testc.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
--- errorlevel 1

Maybe it's a bug in Windows dmd?

-Steve


More information about the Digitalmars-d-learn mailing list