www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D libraries (DLLs and LIBs) from C

reply Federico "Lox" Lucignano <federico alchimiedigitali.net> writes:
Hi guys,
I was wandering if D compiled libraries (.DLL and .LIB) can be used from 
C, if so what are the rules (extern(c), static, etc)?
What can be accessed and what cannot (e.g. classes)?
What will happen if the linked/imported library uses D herror handling and 
code rises an error? How this can be handled in C?
Can .SO libraries be produced with DMD?

While win32 DLLs and the methods of using C libraries are covered by the 
Docs, .LIBs and the methods of using D libraries in C are totally absent.

Thnx in advance
-----------------------------------------------
"When Rome will Fall
Then the World"
Apr 24 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <3427632499891627968750 news.digitalmars.com>, Federico "Lox"
Lucignano says...
Hi guys,
I was wandering if D compiled libraries (.DLL and .LIB) can be used from 
C, if so what are the rules (extern(c), static, etc)?

Let me preface this reply by saying that D's support of Dll's is more akin to C/C++ than Java's handling of .class files. If you're expecting full-on classloading, and reloadable libraries, you're going to be dissapointed. That aside, DMD does make some things easy for you.
What can be accessed and what cannot (e.g. classes)?

Anything prefixed with "export" will become a symbol, visible to *any* program that loads the library. This, however, only applies to methods, functions and static/global data fields. One cannot export an entire class by "export class{/*...*/}", but for what its worth you can export each individual method. Important: you probably want to use "extern(C)" for anything you export since D assumes the D callspec for anything without this prefix. In plain english: "extern(C)" will export a symbol with the name you typed, while no extern statement will mangle the name to match the D symbol convention.
What will happen if the linked/imported library uses D herror handling and 
code rises an error? How this can be handled in C?

It will crash. Horribly. This is a bug in how the exception handling is compiled into DMD .dll files, and will happen regardless if the host application is D or not. A good workaround is to catch *everthing* at all entry points to your dll, and handle the exception intellegently from there. # export extern(C) char[] myHandle(){ # try{ /* do work *? } # catch(Object o){ # return o.toString(); # } # return null; // calling side will be looking for non-null on exception. # }
Can .SO libraries be produced with DMD?

To the best of my knowledge yes, but I do not program under *nix. :(
While win32 DLLs and the methods of using C libraries are covered by the 
Docs, .LIBs and the methods of using D libraries in C are totally absent.

There's really nothing to it. As along as you "export extern(C)" everything, and don't expect to hook the GC (something you don't do by default anyway), it will behave *perfectly* when loaded by a C program. Just watch those exceptions, and beware of how arrays and strings are handled differently between the two languages. - EricAnderton at yahoo
Apr 26 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d4lklr$1m43$1 digitaldaemon.com>, pragma says...
While win32 DLLs and the methods of using C libraries are covered by the 
Docs, .LIBs and the methods of using D libraries in C are totally absent.

There's really nothing to it. As along as you "export extern(C)" everything, and don't expect to hook the GC (something you don't do by default anyway), it will behave *perfectly* when loaded by a C program. Just watch those exceptions, and beware of how arrays and strings are handled differently between the two languages.

I misread your question. My reply (above) still only applies to .dll files. As for linking D .lib files to a C application, your mileage may vary. Honestly, I've never tried that, but I'd imagine that since any D .lib is dependent upon phobos, that pretty much keeps you tied to D. You may be able to break phobos down into .obj files and link those in as needed, but your guess is as good as mine as to how well this will work. IMO, you're better off linking C libs into D, or using D-dlls and leaving it at that. - EricAnderton at yahoo
Apr 26 2005
parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pragma schrieb am Tue, 26 Apr 2005 15:10:04 +0000 (UTC):
 In article <d4lklr$1m43$1 digitaldaemon.com>, pragma says...
While win32 DLLs and the methods of using C libraries are covered by the 
Docs, .LIBs and the methods of using D libraries in C are totally absent.

There's really nothing to it. As along as you "export extern(C)" everything, and don't expect to hook the GC (something you don't do by default anyway), it will behave *perfectly* when loaded by a C program. Just watch those exceptions, and beware of how arrays and strings are handled differently between the two languages.

I misread your question. My reply (above) still only applies to .dll files. As for linking D .lib files to a C application, your mileage may vary. Honestly, I've never tried that, but I'd imagine that since any D .lib is dependent upon phobos, that pretty much keeps you tied to D. You may be able to break phobos down into .obj files and link those in as needed, but your guess is as good as mine as to how well this will work. IMO, you're better off linking C libs into D, or using D-dlls and leaving it at that.

1) remove "dmain.o" from your libphobos.a # ar d libphobos.a dmain.o 2) fetch the C stub and compile it http://paste.debian.net/283 # gcc -c cstub.c 3) fetch the D stub and compile it http://paste.debian.net/284 # dmd -c dstub.d 4) link all together # dmd dstub.o cstub.o modified-libphobo.a 5) enjoy Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCbsnA3w+/yD4P9tIRAk/MAKCwjyg1P2bgl1Br2B8c6GgkLSv8FwCeLMaZ aGBYmLLicsyowDDSoqC4L6k= =Vir+ -----END PGP SIGNATURE-----
Apr 26 2005
next sibling parent Federico "Lox" Lucignano <federico alchimiedigitali.net> writes:
Thank you both pals,
as now I was thinking that noone would reply to that question, it seems that 
I was wrong ;-)

O.K., so... let's say that C -> D linking is the only real possibility as 
long as we want to produce a DLL ;-)

Well... anyone knows how to produce a Linux dll (.so) ? Do .so libraries 
have the same functionalities as DLLs?

I've got a new 80Gb HDD from Maxtor and grabbed MEPIS iso from the web, I'm 
going to install it tomorrow, so if in the meantime someone can post some 
clues on .SO libraries it would be really appreciated.

Thnx in advance ;-)
Apr 26 2005
prev sibling parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Thomas Kuehne schrieb am Wed, 27 Apr 2005 01:07:44 +0200:
 1) remove "dmain.o" from your libphobos.a 
 # ar d libphobos.a dmain.o

 2) fetch the C stub and compile it
 http://paste.debian.net/283
 # gcc -c cstub.c

 3) fetch the D stub and compile it
 http://paste.debian.net/284
 # dmd -c dstub.d 

 4) link all together
 # dmd dstub.o cstub.o modified-libphobo.a

 5) enjoy

Clarification: the code above is for linking D code into a C project. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCbtCo3w+/yD4P9tIRAvjuAJ4qLC84d0xXZKPkQAkhVTNrXNsyfQCglWwc f1XZrNXVNunuNKDYB14P4LA= =HQgE -----END PGP SIGNATURE-----
Apr 26 2005
parent reply Federico "Lox" Lucignano <federico alchimiedigitali.net> writes:
:-D
Bravo, bravo.

Thomas, Thank you very much!

The example code you've posted it's quite illuminating! ;-)

I've only a question:

in the D library to be linked You've declared the Dummy class, then, through 
testLib(), a new Dummy istance is returned through a pointer... But how this 
can be handled in C??? C doesn't support classes... I thought that only
functions 
and pointers to Structs can be handled... Maybe i'm missing something... 
(ok, this really make me feel dumb :-\)
Apr 26 2005
parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Federico Lox Lucignano schrieb am Wed, 27 Apr 2005 00:57:31 +0000 (UTC):
 The example code you've posted it's quite illuminating! ;-)

 I've only a question:

 in the D library to be linked You've declared the Dummy class, then, through 
 testLib(), a new Dummy istance is returned through a pointer... But how this 
 can be handled in C??? C doesn't support classes... I thought that only
functions 
 and pointers to Structs can be handled... Maybe i'm missing something... 
 (ok, this really make me feel dumb :-\)

Classes are reference types in D. You might pass their pointer to C but I think it's difficult to access any of their members from C. Please remember that the code is only a stub. If you want to pass D objects outside and re-use them you'll have to take care of the GC. Either by disabling the GC while holding any references in the C part or by managing an array of objects in the D part and only pass the array index to C. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCbx8U3w+/yD4P9tIRAqqKAJ9rkw9FDlkgpIV3nikFujvXD0nXcACgro/8 vn/aas+VhG9O/L2FcekfwME= =GEN5 -----END PGP SIGNATURE-----
Apr 26 2005
parent reply Federico "Lox" Lucignano <federico alchimiedigitali.net> writes:
Hello Thomas,

 Please remember that the code is only a stub.
 If you want to pass D objects outside and re-use them you'll have to
 take
 care of the GC. Either by disabling the GC while holding any
 references in
 the C part or by managing an array of objects in the D part and only
 pass the array index to C.
 Thomas

Well, so You're telling me that wrapping interactions with D-objects in few functions is the right thing to do ;-) ok, i've got the whole thing but... since I haven't found no trace of it in the reference... How can I disable the GC? And, last but not least, the real problem is only with classes and templates, there should be no difference between a D struct and a C one, right? ----------------------------------------------- "When Rome will Fall Then the World"
Apr 27 2005
parent Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Federico Lox Lucignano schrieb am Wed, 27 Apr 2005 09:50:55 +0000 (UTC):
 Please remember that the code is only a stub.
 If you want to pass D objects outside and re-use them you'll have to
 take
 care of the GC. Either by disabling the GC while holding any
 references in
 the C part or by managing an array of objects in the D part and only
 pass the array index to C.

Well, so You're telling me that wrapping interactions with D-objects in few functions is the right thing to do ;-) ok, i've got the whole thing but... since I haven't found no trace of it in the reference... How can I disable the GC?

http://www.digitalmars.com/d/phobos.html#gc
 And, last but not least, the real problem is only with classes and templates, 
 there should be  no difference between a D struct and a C one, right?

How about the name mangling, invariants etc.? Accessing a C struct is no problem but I've never tried to access a D struct from C. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCb2kZ3w+/yD4P9tIRAg89AKCdK9D+W0R7Q9o4lk4ZleGJWSP/FwCfRc8i JUdKLSGW7/83c5EVTMro6Gg= =aqVv -----END PGP SIGNATURE-----
Apr 27 2005