digitalmars.D - Library Interop
- Deja Augustine (22/22) Aug 06 2004 I've reached the point in D.NET where I'm playing around with calling
- Nick (4/10) Aug 06 2004 I really have no idea, but maybe DMD passes single ints as registers rat...
- Walter (1/1) Aug 06 2004 For D functions, the last argument will be passed in EAX if it fits in E...
- Deja Augustine (8/11) Aug 06 2004 Well, that prevents .NET from directly interacting with D. People will
- Sean Kelly (4/9) Aug 06 2004 Are you sure? How does C++/CLI do the marshalling between managed and u...
- Andy Friesen (8/22) Aug 06 2004 The Managed C++ compiler cheats. :)
- Walter (5/15) Aug 06 2004 EAX.
- Derek (6/7) Aug 06 2004 I guess this only applies to the DMD compiler and 'D' - the language.
- J C Calvarese (9/17) Aug 06 2004 I think that something like that should be compatible from compiler to
- Ilya Minkov (10/15) Aug 07 2004 I guess the docs say something about leaving the calling conventions,
- Walter (4/8) Aug 07 2004 I think the extern(C) fills that role adequately. The C calling conventi...
- Nick (4/12) Aug 08 2004 So I guess this means you will always have to use extern(C) when making ...
- Lars Ivar Igesund (4/15) Aug 08 2004 So why did you invent extern(D)? If you should use extern(C) to create
- J C Calvarese (17/38) Aug 08 2004 I'm trying to understand that, too. I guess it's supposed to be more
- Deja Augustine (15/36) Aug 08 2004 Well, because the D calling convention, as Walter stated, uses the EAX
- Lars Ivar Igesund (4/8) Aug 08 2004 This is not a problem. Prefix all exported symbols with 'export' in code...
I've reached the point in D.NET where I'm playing around with calling native D code from .NET. I'm running into an interesting dilema, as I cannot figure out what D is expecting. This is best demonstrated by a couple examples: If I have a function in a native D DLL: extern (D) void foo(int i) { printf("%i in foo", i); } and I push a 32-bit integer onto the stack prior to the call to that function, it invariably is either printed as some address or as 0. However, if I do the same thing with a function that takes a float and I pass it a 4-byte floating point number, then it Just Works. What does work, with ints, however, is if I do: extern (D) void foo(int i, int j) { printf("%i in foo", i); } and then pass two 32-bit integers. Except that i works and j is that same address regardless of how many integers I push onto the stack. Strings are a similar problem. If foo takes a char[] and I pass it a 32-bit integer representing the length of the string and then I pass a valid pointer to the string, the D end sees the char[] as being empty. I have none of these problems if I use extern (C) so it has to be something with the way that D expects its arguments, and I, for one, am dumbfounded. Does anyone have any insight into this problem? -Deja
Aug 06 2004
In article <cf095i$inp$1 digitaldaemon.com>, Deja Augustine says...If I have a function in a native D DLL: extern (D) void foo(int i) { printf("%i in foo", i); } and I push a 32-bit integer onto the stack prior to the call to that function, it invariably is either printed as some address or as 0. However, if I do the same thing with a function that takes a float and I pass it a 4-byte floating point number, then it Just Works.I really have no idea, but maybe DMD passes single ints as registers rather than on the stack? Have you tried playing around with disassembled D code? Nick
Aug 06 2004
For D functions, the last argument will be passed in EAX if it fits in EAX.
Aug 06 2004
Walter wrote:For D functions, the last argument will be passed in EAX if it fits in EAX.Well, that prevents .NET from directly interacting with D. People will have to rely on extern (C) wrappers (which are already supported) since there's no way to work directly with registers using .NET Maybe by D.NET 2.0 it'll be able to automatically generate the machine code wrapper, but for now there are too many things more important. But that at least solves the mystery. Thanks! Deja
Aug 06 2004
In article <cf0qdu$th6$1 digitaldaemon.com>, Deja Augustine says...Walter wrote:Are you sure? How does C++/CLI do the marshalling between managed and unmanaged code? SeanFor D functions, the last argument will be passed in EAX if it fits in EAX.Well, that prevents .NET from directly interacting with D. People will have to rely on extern (C) wrappers (which are already supported) since there's no way to work directly with registers using .NET
Aug 06 2004
Sean Kelly wrote:In article <cf0qdu$th6$1 digitaldaemon.com>, Deja Augustine says...The Managed C++ compiler cheats. :) It has both a native and a managed code generator, so it can flip between one and the other at will, depending on the function it's compiling. Making a D compiler that can do the same is certainly possible (we already have an x86 code generator in the form of DLI, after all) but a project in and of itself. -- andyWalter wrote:Are you sure? How does C++/CLI do the marshalling between managed and unmanaged code?For D functions, the last argument will be passed in EAX if it fits in EAX.Well, that prevents .NET from directly interacting with D. People will have to rely on extern (C) wrappers (which are already supported) since there's no way to work directly with registers using .NET
Aug 06 2004
"Deja Augustine" <deja scratch-ware.net> wrote in message news:cf0qdu$th6$1 digitaldaemon.com...Walter wrote:EAX.For D functions, the last argument will be passed in EAX if it fits inNo problem, just use the extern (C) calling convention in your D code that you want to interface with .NET. No need for wrappers.Well, that prevents .NET from directly interacting with D. People will have to rely on extern (C) wrappers (which are already supported) since there's no way to work directly with registers using .NET Maybe by D.NET 2.0 it'll be able to automatically generate the machine code wrapper, but for now there are too many things more important. But that at least solves the mystery. Thanks!
Aug 06 2004
On Fri, 6 Aug 2004 12:24:19 -0700, Walter wrote:For D functions, the last argument will be passed in EAX if it fits in EAX.I guess this only applies to the DMD compiler and 'D' - the language. Another D compiler might do it differently. -- Derek Melbourne, Australia
Aug 06 2004
Derek wrote:On Fri, 6 Aug 2004 12:24:19 -0700, Walter wrote:I think that something like that should be compatible from compiler to compiler as much as possible (unless it's platform-dependent). I'm hoping that information will become part of the D standard, e.g. http://www.digitalmars.com/d/abi.html At the minimum, it should be documented. -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/For D functions, the last argument will be passed in EAX if it fits in EAX.I guess this only applies to the DMD compiler and 'D' - the language. Another D compiler might do it differently.
Aug 06 2004
J C Calvarese schrieb:I think that something like that should be compatible from compiler to compiler as much as possible (unless it's platform-dependent). I'm hoping that information will become part of the D standard, e.g. http://www.digitalmars.com/d/abi.htmlIt is platform-dependent. :)At the minimum, it should be documented.I guess the docs say something about leaving the calling conventions, memory layouts, etc. unspecified, so that these can be tuned to performance in future. Instead, all communication with other language runtimes should happen via extern(...) interfaces. However, one could think of disigning another extern interface to standardize a link-compatible interface to D features, where performance is not essential. -eye
Aug 07 2004
"Ilya Minkov" <minkov cs.tum.edu> wrote in message news:cf26tn$1n01$1 digitaldaemon.com...Instead, all communication with other language runtimes should happen via extern(...) interfaces. However, one could think of disigning another extern interface to standardize a link-compatible interface to D features, where performance is not essential.I think the extern(C) fills that role adequately. The C calling convention is the lingua franca on most platforms, another one is not needed.
Aug 07 2004
In article <cf3275$22h3$1 digitaldaemon.com>, Walter says..."Ilya Minkov" <minkov cs.tum.edu> wrote in message news:cf26tn$1n01$1 digitaldaemon.com...So I guess this means you will always have to use extern(C) when making shared libraries? NickInstead, all communication with other language runtimes should happen via extern(...) interfaces. However, one could think of disigning another extern interface to standardize a link-compatible interface to D features, where performance is not essential.I think the extern(C) fills that role adequately. The C calling convention is the lingua franca on most platforms, another one is not needed.
Aug 08 2004
Walter wrote:"Ilya Minkov" <minkov cs.tum.edu> wrote in message news:cf26tn$1n01$1 digitaldaemon.com...So why did you invent extern(D)? If you should use extern(C) to create interoperable libraries, it is kinda stupid to have extern(D) as default. Lars Ivar IgesundInstead, all communication with other language runtimes should happen via extern(...) interfaces. However, one could think of disigning another extern interface to standardize a link-compatible interface to D features, where performance is not essential.I think the extern(C) fills that role adequately. The C calling convention is the lingua franca on most platforms, another one is not needed.
Aug 08 2004
Lars Ivar Igesund wrote:Walter wrote:I'm trying to understand that, too. I guess it's supposed to be more efficient. Maybe the name extern(D) should be renamed to extern(DMD) if it's going to be proprietary and undocumented. I don't know whether studying the public front end code would be enough to explain what makes extern(D) special. Perhaps Walter is saying: Use extern(C) for now [but later when extern(D) is documented and standarized, you could probably use it, too]. (I don't know that he's stated the important bracketed part yet, but this topic is pretty much over my head.) So there's no problem right now (we can use the C way) and the situation will even improve in the future when the D way becomes an option. We can hope anyway. :) -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/"Ilya Minkov" <minkov cs.tum.edu> wrote in message news:cf26tn$1n01$1 digitaldaemon.com...So why did you invent extern(D)? If you should use extern(C) to create interoperable libraries, it is kinda stupid to have extern(D) as default. Lars Ivar IgesundInstead, all communication with other language runtimes should happen via extern(...) interfaces. However, one could think of disigning another extern interface to standardize a link-compatible interface to D features, where performance is not essential.I think the extern(C) fills that role adequately. The C calling convention is the lingua franca on most platforms, another one is not needed.
Aug 08 2004
Lars Ivar Igesund wrote:Walter wrote:Well, because the D calling convention, as Walter stated, uses the EAX register for the last parameter. Since the majority of functions will have 0-1 arguments, this is a pretty decent speed increase since most of the time, the argument will already be there from a previous operation. Since D's default behavior is interacting with other D applications, it makes sense that extern(D) should be the default so as to default to the increased speed. If you're interoping with something that can't take advantage of that, then you use the extern(C) to use the standard C calling convention. As a point of note, creating a DLL that actually exports extern(D) code is a major pain in the rear since you have to figure out the mangled name of your method and put THAT into your .def file. So having to use extern(C) to interop with .NET makes life easier in other ways as well. -Deja"Ilya Minkov" <minkov cs.tum.edu> wrote in message news:cf26tn$1n01$1 digitaldaemon.com...So why did you invent extern(D)? If you should use extern(C) to create interoperable libraries, it is kinda stupid to have extern(D) as default. Lars Ivar IgesundInstead, all communication with other language runtimes should happen via extern(...) interfaces. However, one could think of disigning another extern interface to standardize a link-compatible interface to D features, where performance is not essential.I think the extern(C) fills that role adequately. The C calling convention is the lingua franca on most platforms, another one is not needed.
Aug 08 2004
Deja Augustine wrote:As a point of note, creating a DLL that actually exports extern(D) code is a major pain in the rear since you have to figure out the mangled name of your method and put THAT into your .def file. So having to use extern(C) to interop with .NET makes life easier in other ways as well.This is not a problem. Prefix all exported symbols with 'export' in code and you can omit the symbols from the .def file altogether. Lars Ivar Igesund
Aug 08 2004