www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - calling D from C

reply gbatyan yahoo.com writes:
Is there a way to use D from C?

What is the simple yet portable way to do the following:

- have an imaginary C/C++ SDK giving a possibility to register a
callback function to be called upon some event in SDK.
- want to implement the callback functionality in D.
- If possible, make the whole thing be thread-safe
(If SDK wishes to have several threads calling the callback concurrently).

Regards!
Dec 07 2004
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
gbatyan wrote:

 Is there a way to use D from C?

You can declare your functions as "extern(C)", which makes them callable from regular C too. You have to be really careful with garbage collected objects and exceptions, though... But I've used it for simple GLUT callbacks ? --anders PS. Mapping "bit" is left an as an exercise :-)
Dec 07 2004
parent reply gbatyan yahoo.com writes:
In article <cp3u7q$aou$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
gbatyan wrote:

 Is there a way to use D from C?

You can declare your functions as "extern(C)", which makes them callable from regular C too. You have to be really careful with garbage collected objects and exceptions, though... But I've used it for simple GLUT callbacks ? --anders PS. Mapping "bit" is left an as an exercise :-)

what about type conversion, in a D function exported to C - am I able to use D structs and dynamic arrays? How should those be declared in C? How to cope with the fact that C and D may use different alignments in structs? P.S., excuse me, :-) where do I find the article how exactly this extern (C) syntax looks like? I mean Not extern (C) when importing c functions into d, but instead for exporting d functions to c?
Dec 07 2004
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
gbatyan wrote:

 what about type conversion, in a D function exported to C - am I able
 to use D structs and dynamic arrays?

Not really arrays, since they are garbage collected in D... But the definition is something like { int len; void *data; } Structs should be more or less similar, though ?
 How should those be declared in C? How to cope with the fact that C and D
 may use different alignments in structs?

You will have to explicitly align them then.
 P.S., excuse me, :-) where do I find the article how exactly this extern (C)
 syntax looks like? I mean Not extern (C) when importing c functions into d, but
 instead for exporting d functions to c?

It's the same syntax :-) C linkage is C linkage. It mostly affects the function name "mangling". --anders
Dec 07 2004
next sibling parent reply gbatyan yahoo.com writes:
In article <cp420a$hf6$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
gbatyan wrote:

 what about type conversion, in a D function exported to C - am I able
 to use D structs and dynamic arrays?

Not really arrays, since they are garbage collected in D... But the definition is something like { int len; void *data; } Structs should be more or less similar, though ?
 How should those be declared in C? How to cope with the fact that C and D
 may use different alignments in structs?

You will have to explicitly align them then.
 P.S., excuse me, :-) where do I find the article how exactly this extern (C)
 syntax looks like? I mean Not extern (C) when importing c functions into d, but
 instead for exporting d functions to c?

It's the same syntax :-) C linkage is C linkage. It mostly affects the function name "mangling".

is name mangling standardised across D implementations? Regards!
Dec 07 2004
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
gbatyan wrote:

It's the same syntax :-) C linkage is C linkage.
It mostly affects the function name "mangling".

excuse me for endless newbieness, but where can I read about name mangling? is name mangling standardised across D implementations?

I'm not sure if name mangling in D is either documented or even standard among D compilers, but you can read more about mangling in general: http://en.wikipedia.org/wiki/Name_mangling Looking at the disassembled output for some D code should give you examples of what D does ? --anders
Dec 07 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:cp4v4t$223h$3 digitaldaemon.com...
 gbatyan wrote:

It's the same syntax :-) C linkage is C linkage.
It mostly affects the function name "mangling".

excuse me for endless newbieness, but where can I read about name


 is name mangling standardised across D implementations?

I'm not sure if name mangling in D is either documented or even standard among D compilers, but you can read more about mangling in general: http://en.wikipedia.org/wiki/Name_mangling Looking at the disassembled output for some D code should give you examples of what D does ?

No need to worry about name mangling, as declaring functions with extern(C) will cause them to match C's name mangling.
Dec 07 2004
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

I'm not sure if name mangling in D is either
documented or even standard among D compilers,
but you can read more about mangling in general:
http://en.wikipedia.org/wiki/Name_mangling

Looking at the disassembled output for some D
code should give you examples of what D does ?

No need to worry about name mangling, as declaring functions with extern(C) will cause them to match C's name mangling.

Right, "extern (C)" avoids most of the mangling. Is there a link to the names / ABI used for D ? (when declaring them as the usual, "extern(D)") Or is not supported to call D routines from C ? (as there is plenty of issues with that anyway) I could only find the page with mostly "TBD", i.e. http://www.digitalmars.com/d/abi.html Not that it matters much, to the casual D developer. I guess it's only useful for disassembly/debugging... --anders
Dec 07 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:cp56qd$2fhg$1 digitaldaemon.com...
 Is there a link to the names / ABI used for D ?
 (when declaring them as the usual, "extern(D)")

I should write one, but at the moment all there is is the source code for the mangler, mangle.c.
 Or is not supported to call D routines from C ?
 (as there is plenty of issues with that anyway)

It's not officially supported, though if you know what you're doing, you can make it work. But no need to bother, that's what the C interface support is for.
Dec 07 2004
parent reply Sean Kelly <sean f4.ca> writes:
Walter wrote:
 "Anders F Björklund" <afb algonet.se> wrote in message
 news:cp56qd$2fhg$1 digitaldaemon.com...
 
Is there a link to the names / ABI used for D ?
(when declaring them as the usual, "extern(D)")

I should write one, but at the moment all there is is the source code for the mangler, mangle.c.

Out of curiosity, will D 1.0 have specific ABI requirements? I've been wondering whether it will be safe (or even possible) to share user-defined objects between units that may have been compiled with different compilers. Sean
Dec 08 2004
parent "Walter" <newshound digitalmars.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message
news:cp7agn$2huq$1 digitaldaemon.com...
 Out of curiosity, will D 1.0 have specific ABI requirements?  I've been
 wondering whether it will be safe (or even possible) to share
 user-defined objects between units that may have been compiled with
 different compilers.

It'll be as safe as mixing objects compiled with different C compilers.
Dec 08 2004
prev sibling parent reply John Reimer <brk_6502 yahoo.com> writes:
Walter wrote:

 
 "Anders F Björklund" <afb algonet.se> wrote in message
 news:cp4v4t$223h$3 digitaldaemon.com...
 gbatyan wrote:

It's the same syntax :-) C linkage is C linkage.
It mostly affects the function name "mangling".

excuse me for endless newbieness, but where can I read about name


 is name mangling standardised across D implementations?

I'm not sure if name mangling in D is either documented or even standard among D compilers, but you can read more about mangling in general: http://en.wikipedia.org/wiki/Name_mangling Looking at the disassembled output for some D code should give you examples of what D does ?

No need to worry about name mangling, as declaring functions with extern(C) will cause them to match C's name mangling.

Not strictly. Declaring extern(C) only works if you do it within the global module scope (I guess that's where it's assumed to be used?). I've found that if you try to declare functions extern(C) within a class, you lose access to those functions at link time because their symbol names become part of the package/module namespace no matter what you intended with the extern(C) declaration. :-)
Dec 07 2004
parent reply J C Calvarese <jcc7 cox.net> writes:
John Reimer wrote:
 Walter wrote:
 
 
"Anders F Björklund" <afb algonet.se> wrote in message
news:cp4v4t$223h$3 digitaldaemon.com...

gbatyan wrote:


It's the same syntax :-) C linkage is C linkage.
It mostly affects the function name "mangling".

excuse me for endless newbieness, but where can I read about name


mangling?
is name mangling standardised across D implementations?

I'm not sure if name mangling in D is either documented or even standard among D compilers, but you can read more about mangling in general: http://en.wikipedia.org/wiki/Name_mangling Looking at the disassembled output for some D code should give you examples of what D does ?

No need to worry about name mangling, as declaring functions with extern(C) will cause them to match C's name mangling.

Not strictly. Declaring extern(C) only works if you do it within the global module scope (I guess that's where it's assumed to be used?). I've found that if you try to declare functions extern(C) within a class, you lose access to those functions at link time because their symbol names become part of the package/module namespace no matter what you intended with the extern(C) declaration. :-)

OK, but couldn't you get around that with a pretty simple wrapper function? Something like this... class myClass { this(){} void someFn(){} } extern(C) void fnForC() {myClass c = new myClass(); c.someFn } Sounds like more fun that worrying about name mangling. -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Dec 08 2004
parent reply John Reimer <brk_6502 yahoo.com> writes:
J C Calvarese wrote:
 John Reimer wrote:
 Not strictly.  Declaring extern(C) only works if you do it within the 
 global
 module scope (I guess that's where it's assumed to be used?).  I've found
 that if you try to declare functions extern(C) within a class, you lose
 access to those functions at link time because their symbol names become
 part of the package/module namespace no matter what you intended with the
 extern(C) declaration. :-)

OK, but couldn't you get around that with a pretty simple wrapper function? Something like this... class myClass { this(){} void someFn(){} } extern(C) void fnForC() {myClass c = new myClass(); c.someFn } Sounds like more fun that worrying about name mangling.

Hi Justin, Well, I was no longer talking about "calling D from C." (your example being a perfect example of how to do that). Here, I was playing a little devil's advocate. My point was concerning use of extern(C) and its limitations in scope. In order to work, it must never be used anywhere beyond global module scope. Yet, there /are/ ways around that: module a; extern(C) { void function1(); void function2(); } module b; class A { import a; } Now we can call extern(C) functions as if they were class members! I suppose there's also a way to use the "alias" keyword to accomplish this too. But, you /cannot/ do: module b; class A { // get access to functions from an external library extern(C) function1(); extern(C) function2(); } ... and expect your app to link properly. Interesting, eh? But importing inside a class is not a wise idea because of name lookup rules. It can cause inadvertant name hiding of other "real" member symbols. But all that's been discussed before. :-) My point probably was a waste of time. I just got the urge to clarify the extent of extern(C)'s usefulness. Urges are rarely a good thing... so take it all with a grain of salt. ;-) - John
Dec 08 2004
parent reply J C Calvarese <jcc7 cox.net> writes:
In article <cp6tcg$1qu1$1 digitaldaemon.com>, John Reimer says...
J C Calvarese wrote:
 John Reimer wrote:
 Not strictly.  Declaring extern(C) only works if you do it within the 
 global
 module scope (I guess that's where it's assumed to be used?).  I've found
 that if you try to declare functions extern(C) within a class, you lose
 access to those functions at link time because their symbol names become
 part of the package/module namespace no matter what you intended with the
 extern(C) declaration. :-)



..
Hi Justin,

Well, I was no longer talking about "calling D from C." (your example 

I guess I missed the shift. :)
My point probably was a waste of time.  I just got the urge to clarify 
the extent of extern(C)'s usefulness.  Urges are rarely a good thing... 
so take it all with a grain of salt. ;-)

No, I think you raised an interesting issue. Maybe D shouldn't allow us to put extern(C) on class members since it's not particularly helpful. Or are you trying to convince Walter to eliminate name mangling in that case, so that extern(C) would be actually useful within a class? jcc7
Dec 08 2004
parent John Reimer <brk_6502 yahoo.com> writes:
J C Calvarese wrote:
 In article <cp6tcg$1qu1$1 digitaldaemon.com>, John Reimer says...
 
J C Calvarese wrote:

John Reimer wrote:

Not strictly.  Declaring extern(C) only works if you do it within the 
global
module scope (I guess that's where it's assumed to be used?).  I've found
that if you try to declare functions extern(C) within a class, you lose
access to those functions at link time because their symbol names become
part of the package/module namespace no matter what you intended with the
extern(C) declaration. :-)



..
Hi Justin,

Well, I was no longer talking about "calling D from C." (your example 

I guess I missed the shift. :)
My point probably was a waste of time.  I just got the urge to clarify 
the extent of extern(C)'s usefulness.  Urges are rarely a good thing... 
so take it all with a grain of salt. ;-)

No, I think you raised an interesting issue. Maybe D shouldn't allow us to put extern(C) on class members since it's not particularly helpful. Or are you trying to convince Walter to eliminate name mangling in that case, so that extern(C) would be actually useful within a class? jcc7

I was pointing out a inconsistancy with the use of extern(C), such that it's use could be confusing in certain situations: you can import a module containing extern(C)'s into a class and it works, yet you cannot declare extern(C)'s within a class and expect it to link. I realize it could get unreasonably complicated fixing these kinds of issues, so I'm not sure what kind of a solution is preferable. I guess it's just important to understand that D's simplicity sometimes allows the creative programmer to do some unusual things without the compiler reporting a problem. Eventually, one does find out that something can't be done, but not necessarily via a standard error message. :-) At present, the best solution perhaps is to stay informed, that is, to know how D works and stay away from such counter-productive techniques. If a solution is implemented that prevents such methods, all the better, because it will keep new developers from repeating the same mistake over and over again. Sometimes "logical" programming methods don't produce the expected result. Later, John
Dec 08 2004
prev sibling parent "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:cp420a$hf6$1 digitaldaemon.com...
 How should those be declared in C? How to cope with the fact that C and


 may use different alignments in structs?


The default struct alignment in D will match that of C's default alignment.
Dec 07 2004
prev sibling parent Ilya Minkov <minkov cs.tum.edu> writes:
This question was answered already in the old newsgroups, and must be in 
the web archive on the digitalmars site.

One important thing is: if you have a D application, the startup code 
which calls main(...) will initialize the D runtime correctly. If you 
have a C or C++ application, you will need to initialize it manually. 
Get a clue on what is requiered from here:

http://www.digitalmars.com/d/windows.html

-eye

gbatyan yahoo.com schrieb:
 Is there a way to use D from C?
 
 What is the simple yet portable way to do the following:
 
 - have an imaginary C/C++ SDK giving a possibility to register a
 callback function to be called upon some event in SDK.
 - want to implement the callback functionality in D.
 - If possible, make the whole thing be thread-safe
 (If SDK wishes to have several threads calling the callback concurrently).
 
 Regards!
 
 

Dec 08 2004