Calling C functions

Andrej Mitrovic andrej.mitrovich at gmail.com
Thu Dec 9 08:38:00 PST 2010


I know I prefer using shared() when interfacing with C.

I've tried using __gshared once when interfacing with C code. But I
had crashes all the time, using shared instead made my app stable
again. It might be related to the way the C code worked, since
multiple threads were involved. Anyway.. that's my experience with
gshared..

On 12/9/10, Steven Schveighoffer <schveiguy at yahoo.com> wrote:
> On Thu, 09 Dec 2010 10:15:59 -0500, CrypticMetaphor
> <CrypticMetaphor88 at gmail.com> wrote:
>
>> On 12/9/2010 3:57 PM, Steven Schveighoffer wrote:
>>> 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
>>
>> 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
>


More information about the Digitalmars-d-learn mailing list