So I'm all trying out this hot new shared switch, and it works just dandy for -m32 when d has the main function. But now I want to be able to call my shared lib from C.

my little shared lib, tup.d:


import std.stdio;
extern(C) void xyz(int i){
    writeln(i);
}


compiled like so:

dmd -shared -m32 tup.d -oflibtup.so

my little C program, tok.c:

extern void xyz(int);

int main(int argc, char **argv){
    xyz(1);
}


compiled like so:

gcc -m32 tok.c -L. -ltup

Oh no!

./libtup.so: undefined reference to `_deh_beg'
./libtup.so: undefined reference to `_tlsend'
./libtup.so: undefined reference to `_tlsstart'
./libtup.so: undefined reference to `_deh_end'
collect2: ld returned 1 exit status


It seems like I've run into this before with static libs, but I'll ask again anyways. What the heck are these symbols for?

looking in druntime, I find

extern (C)
{
    extern __gshared
    {
        void* _deh_beg;
        void* _deh_end;
    }

So I guess I have to put those in tok.c? And then start druntime?

Okay, fine. add

void *_deh_beg;
void *_deh_end;
__thread void *_tlsstart;
__thread void *_tlsend;

to tok.c

Then everything compiles, but a.out segfaults. I guess it didn't start druntime on its own.

so add to tup.d

extern shared bool _D2rt6dmain212_d_isHaltingOb;
alias _D2rt6dmain212_d_isHaltingOb _d_isHalting;
extern(C) {

    void rt_init();
    void rt_term();

    void _init() {
        rt_init();
    }

    void _fini() {
        if(!_d_isHalting){
            rt_term();
        }
    }

}

then dmd complains about _fini and _init being multiply defined. what to do?

Reply via email to