Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Linking C files to D object files

Moderators: larsivi kris

Posted: 10/17/08 20:45:44

I have library of D functions I want to call from a C program. They are wrapped in extern(C). I'm using dmd on linux.

Under phobos the following results in a working program:

dmd -c emptymain.d mylibrary.d
gcc myprogram.c emptymain.o mylibrary.o -o myprog -lphobos -lpthread -lm

Under tango ld dies with a "multiple definition of `main'" error.

I read a prior discussion on link library order but moving libpthread & libm before the tango libraries didn't fix it.

Any ideas on how to make this work?

-hauptmech

Author Message

Posted: 10/18/08 18:45:26

It is possible like shown in DLL example on digitalmars.com. You need to initialize the runtime and GC and make sure they are shutdown also. And your D code does not have a main.

Or you can invert the call side, to have your C code called from D. If that is doable, i would prefer that.

Posted: 10/18/08 21:57:11

keinfarbton,

Thanks for the reply. I am not having any problem with the GC (which I am not using anyway) or _ctor symbols when linking so I assume the linker has happily found them.

The linker (ld) chooses the main() in my C file over the main() in the D object file when linking with Phobos. No errors, the software runs, I'm happy. Now I want to use Tango but when linking with Tango it chokes with only the "multiple definition of `main'" error, no other errors.

Every language can access the C ABI but few access the D ABI. Meanwhile I like the D language. This is why I'm doing it this way.

-hauptmech

Posted: 10/19/08 09:13:27

You say with phobos the same program has worked allready? It is a tango only problem?

If the linker complains about two main symbols, why don't you remove the not needed one?

Posted: 10/19/08 11:22:20

Frank, it is not that easy. In order to get the Tango run-time going you need to call rt_init(), and on termination rt_term(). These ones are in libtango-base-dmd.a, not in libtango-user-dmd.a. As soon as you add -ltango-base-dmd, you get a main function for free. Glancing over the sources of dmain2, I did not spot differences between phobos and tango, so it is weird that the phobos version allegedly works as expected. I say "allegedly" because I suspect the gc not being initialized properly.

hauptmech, AFAICT, your best bet is to turn you D stuff into a shared lib and dlopen() it from C. I think it should work along the lines of

dlopen your .so bind function rt_init and call it bind your other functions bind rt_term and call that atexit().

This just leaves you with the problem of creating a shared lib... Untested:

dmd -c -fPIC -I/opt/dmd/import -version=tango -version=Posix dfunc.d
gcc -m32 -L/opt/dmd/lib -shared -o foo.so dfunc.o -ltango-user-dmd -ltango-base-dmd 

Please report back if that works.

Ciao

Tom

Posted: 10/24/08 07:45:07

TomD,

Thanks for your suggestion. It will be a while before I try this but I'll let you know the results when I do.

Cheers,

-hauptmech