Thread overview
reading a global external (C) char* in D2
Apr 18, 2010
Graham Fawcett
Apr 18, 2010
Graham Fawcett
April 18, 2010
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
April 18, 2010
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
April 18, 2010
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

April 18, 2010
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