www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - reading a global external (C) char* in D2

reply Graham Fawcett <fawcett uwindsor.ca> writes:
Hi folks,

I'm having trouble reading an external(C) global value in D2. I think
I'm using __gshared properly to sidestep the TLS issues, but I'm still
getting an incorrect result.

Consider the two following programs, one in C, the other D2:

    // testc.c
    #include <stdio.h>
    extern char *gdbm_version;	// or #include <gdbm.h>

    int main() {
      printf("VERSION (C): %s.\n", gdbm_version);
    }

$ gcc -o testc testc.c -lgdbm && ./testc
VERSION (C): GDBM version 1.8.3. 10/15/2002 (built Nov  5 2008 02:36:47).

    // testd.d
    import std.stdio;
    import std.conv;

    __gshared extern (C) char *gdbm_version;

    void main() {
      string v = to!string(gdbm_version);
      writef("VERSION (D): %s.\n", v);
    }

$ dmd testd.d -L-lgdbm && ./testd
VERSION (D): .

Am I doing something wrong? 

Thanks,
Graham
Apr 18 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Graham Fawcett wrote:
 Hi folks,
 
 I'm having trouble reading an external(C) global value in D2. I think
 I'm using __gshared properly to sidestep the TLS issues, but I'm still
 getting an incorrect result.
 
 Consider the two following programs, one in C, the other D2:
 
     // testc.c
     #include <stdio.h>
     extern char *gdbm_version;	// or #include <gdbm.h>
 
     int main() {
       printf("VERSION (C): %s.\n", gdbm_version);
     }
 
 $ gcc -o testc testc.c -lgdbm && ./testc
 VERSION (C): GDBM version 1.8.3. 10/15/2002 (built Nov  5 2008 02:36:47).
 
     // testd.d
     import std.stdio;
     import std.conv;
 
     __gshared extern (C) char *gdbm_version;
 
     void main() {
       string v = to!string(gdbm_version);
       writef("VERSION (D): %s.\n", v);
     }
 
 $ dmd testd.d -L-lgdbm && ./testd
 VERSION (D): .
 
 Am I doing something wrong? 
 
 Thanks,
 Graham
Try adding a second 'extern': extern(C) extern __gshared char* gdbm_version; -Lars
Apr 18 2010
parent reply Graham Fawcett <fawcett uwindsor.ca> writes:
On Sun, 18 Apr 2010 19:14:33 +0200, Lars T. Kyllingstad wrote:

 Graham Fawcett wrote:
 Hi folks,
 
 I'm having trouble reading an external(C) global value in D2. I think
 I'm using __gshared properly to sidestep the TLS issues, but I'm still
 getting an incorrect result.
 
 Consider the two following programs, one in C, the other D2:
 
     // testc.c
     #include <stdio.h>
     extern char *gdbm_version;	// or #include <gdbm.h>
 
     int main() {
       printf("VERSION (C): %s.\n", gdbm_version);
     }
 
 $ gcc -o testc testc.c -lgdbm && ./testc VERSION (C): GDBM version
 1.8.3. 10/15/2002 (built Nov  5 2008 02:36:47).
 
     // testd.d
     import std.stdio;
     import std.conv;
 
     __gshared extern (C) char *gdbm_version;
 
     void main() {
       string v = to!string(gdbm_version);
       writef("VERSION (D): %s.\n", v);
     }
 
 $ dmd testd.d -L-lgdbm && ./testd
 VERSION (D): .
 
 Am I doing something wrong?
 
 Thanks,
 Graham
Try adding a second 'extern': extern(C) extern __gshared char* gdbm_version;
That did it! Thank you. I have much to learn. Cheers, Graham
 
 -Lars
Apr 18 2010
parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Graham Fawcett wrote:
 On Sun, 18 Apr 2010 19:14:33 +0200, Lars T. Kyllingstad wrote:
 
 Graham Fawcett wrote:
 Hi folks,

 I'm having trouble reading an external(C) global value in D2. I think
 I'm using __gshared properly to sidestep the TLS issues, but I'm still
 getting an incorrect result.

 [...]

 Am I doing something wrong?

 Thanks,
 Graham
Try adding a second 'extern': extern(C) extern __gshared char* gdbm_version;
That did it! Thank you. I have much to learn.
No problem. :) I ran into the same issue myself a few weeks ago, and it took a while before I figured it out. I believe the explanation is that - 'extern(C)' means that it is a C variable, i.e. its name isn't mangled like a D variable in the object file. - 'extern' means that it's not a part of the current module, and has to be linked in from elsewhere. -Lars
Apr 18 2010