On 12/9/2010 5:28 PM, Steven Schveighoffer wrote:
On Thu, 09 Dec 2010 10:15:59 -0500, CrypticMetaphor
<crypticmetapho...@gmail.com> wrote:

On 12/9/2010 3:57 PM, Steven Schveighoffer wrote:
On Thu, 09 Dec 2010 09:37:03 -0500, CrypticMetaphor
<crypticmetapho...@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:

ste...@steve-laptop:~/testd$ gcc -c testc.c
ste...@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

Yeah I am using D2

dmc version: 8.42n
dmd version: 2.050

Windows XP. But yeah, it compiles

here is a screenshot:
http://img813.imageshack.us/img813/8230/testu.gif

So I gotta read more about threads eh? But that's all the way at the
end of the book :-(

No, not really. TLS is related to threads, but you don't really have to
understand how threads work to understand where things are stored.

I don't know where it is in the book, but try looking for Thread Local
Storage in the index?

But anyway, it should not compile right?

Should I submit a bug report or something?

Yes please, and be sure to specify that it correctly does not compile on
linux. http://d.puremagic.com/issues/enter_bug.cgi

And how I supposed to call the c function?

Mark the extern(C) integer as __gshared in D. That will put it in the
global namespace instead of TLS.

e.g.:

extern(C) { // this is needed to make it available from C
__gshared int globalFromD;
}

-Steve

Alright then!

I submitted a my first bug report and added __gshared in front of globalFromD and the output was:

100
500

So it worked. thanks!

Reply via email to