digitalmars.D.learn - extern (D)?
- Rob T (9/9) Jan 17 2013 The usual way to link in D libs into D code is to include the
- Justin Whear (4/13) Jan 17 2013 You can use "extern(D)" or simply "extern"; this is described here:
- Rob T (4/8) Jan 17 2013 So there is an extern (D), excellent! Slightly embarrassed I
- Johannes Pfau (14/19) Jan 18 2013 BTW: I wonder how export should be used? It seems like it
- Andrej Mitrovic (5/9) Jan 17 2013 The other way is to use D interface files, which the compiler can
- Rob T (11/18) Jan 17 2013 The documentation says that the interface files will only contain
- Andrej Mitrovic (6/9) Jan 17 2013 There was a recent pull that implemented better header generation
- Rob T (18/31) Jan 18 2013 That pull will make things better, but it doesn't go far enough.
- Jacob Carlborg (11/20) Jan 17 2013 You cannot both have CTFE/inlining/templates and hide the source code.
- Rob T (11/22) Jan 18 2013 Yes I am aware of that limitation, nothing can be done except
- Simon (25/48) Jan 18 2013 Yes you can. I do it with a library of mine; most of it is compiled into...
- Jacob Carlborg (40/43) Jan 18 2013 Yes, it's supposed to work. Just create a class as you normally would
The usual way to link in D libs into D code is to include the required D module source files, but that gives away all of the source code which in some instances is not possible to do (eg legal reasons). The other way is to create a c-style API using extern (C), but that means translating some structures from D to C, and then from C back to D which is not a nice solution. As far as I know, there's no extern (D), but maybe there is something like it available. Anyone know? --rt
Jan 17 2013
On Fri, 18 Jan 2013 02:01:52 +0100, Rob T wrote:The usual way to link in D libs into D code is to include the required D module source files, but that gives away all of the source code which in some instances is not possible to do (eg legal reasons). The other way is to create a c-style API using extern (C), but that means translating some structures from D to C, and then from C back to D which is not a nice solution. As far as I know, there's no extern (D), but maybe there is something like it available. Anyone know? --rtYou can use "extern(D)" or simply "extern"; this is described here: http://dlang.org/attribute.html#linkage Justin
Jan 17 2013
On Friday, 18 January 2013 at 01:07:05 UTC, Justin Whear wrote:You can use "extern(D)" or simply "extern"; this is described here: http://dlang.org/attribute.html#linkage JustinSo there is an extern (D), excellent! Slightly embarrassed I didn't find this for myself. --rt
Jan 17 2013
Am Fri, 18 Jan 2013 01:07:05 +0000 (UTC) schrieb Justin Whear <justin economicmodeling.com>:You can use "extern(D)" or simply "extern"; this is described here: http://dlang.org/attribute.html#linkage JustinBTW: I wonder how export should be used? It seems like it currently does nothing (because we only use static linking?). If we ever wanted to ship phobos as a DLL, wouldn't we have to mark all functions in phobos as export? NOTE: Shared libraries on POSIX traditionally export all their members by default. There are some people trying to change that as exporting all members can cause performance problems: http://gcc.gnu.org/wiki/Visibility http://software.intel.com/en-us/blogs/2010/11/10/limit-performance-impact-of-global-symbols-on-linux http://www.technovelty.org/code/why-symbol-visibility-is-good.html So we might consider if we want to hide members in shared objects by default.
Jan 18 2013
On 1/18/13, Rob T <alanb ucora.com> wrote:The usual way to link in D libs into D code is to include the required D module source files, but that gives away all of the source code which in some instances is not possible to do (eg legal reasons). The other way..The other way is to use D interface files, which the compiler can automatically generate for you if you pass the -H switch. Also use the -op switch if you're generating multiple files at once, which will preserve directory paths.
Jan 17 2013
On Friday, 18 January 2013 at 02:08:46 UTC, Andrej Mitrovic wrote:The other way is to use D interface files, which the compiler can automatically generate for you if you pass the -H switch. Also use the -op switch if you're generating multiple files at once, which will preserve directory paths.The documentation says that the interface files will only contain the parts of a module's source code that is required for linking, however I read somewhere that it pretty much does nothing but strip out the comments because it needs the full source code for a inlining, CTFE, and templates. So I'd have to manually modify or construct them manually, which means I'll lose some abilities, but that may be OK for some situations. For classes and structs, I have no idea how to leave out the implementation details. --rt
Jan 17 2013
On 1/18/13, Rob T <alanb ucora.com> wrote:however I read somewhere that it pretty much does nothing but strip out the comments because it needs the full source code for a inlining, CTFE, and templates.There was a recent pull that implemented better header generation (https://github.com/D-Programming-Language/dmd/pull/1487), it will be in the 2.062 release (which might be a long time from now but it's worth knowing). It's probably doing a better job at hiding implementation details.
Jan 17 2013
On Friday, 18 January 2013 at 04:46:46 UTC, Andrej Mitrovic wrote:On 1/18/13, Rob T <alanb ucora.com> wrote:That pull will make things better, but it doesn't go far enough. For example it would be nice to have extra control, such as the option of telling the compiler to leave out templates and warn or error if auto returns are discovered (or better, convert the auto into a known type). The idea for some people is to hide as much implementation details as possible, so the compiler should be made to help do that kind of job. Also users may want to leave out templates in some cases. As it is, we have to hack them out manually, but that is a time waster and error prone. I wonder if the UDA concept can be used to mark things so that they get left out of the DI or included in the DI? Ultimately the module system itself should be given another shake, I find that it is too simplistic. It would be far better if the module system had true interfacing constructs so that the programmer can specify what gets placed into the DI. --rthowever I read somewhere that it pretty much does nothing but strip out the comments because it needs the full source code for a inlining, CTFE, and templates.There was a recent pull that implemented better header generation (https://github.com/D-Programming-Language/dmd/pull/1487), it will be in the 2.062 release (which might be a long time from now but it's worth knowing). It's probably doing a better job at hiding implementation details.
Jan 18 2013
On 2013-01-18 05:37, Rob T wrote:The documentation says that the interface files will only contain the parts of a module's source code that is required for linking, however I read somewhere that it pretty much does nothing but strip out the comments because it needs the full source code for a inlining, CTFE, and templates. So I'd have to manually modify or construct them manually, which means I'll lose some abilities, but that may be OK for some situations.You cannot both have CTFE/inlining/templates and hide the source code. It's the same as in C++.For classes and structs, I have no idea how to leave out the implementation details.You can either use an interface or just not provide an implementation for the methods. Note that it's perfectly fine to have a method in D without an implementation even it's not abstract. This is to support the use case you have here and separate compilation. I guess you would need to list the fields on classes/structs, again that's just like C++. -- /Jacob Carlborg
Jan 17 2013
On Friday, 18 January 2013 at 07:34:35 UTC, Jacob Carlborg wrote:You cannot both have CTFE/inlining/templates and hide the source code. It's the same as in C++.Yes I am aware of that limitation, nothing can be done except lose the flexibility of templates and so forth, or keep it and expose the source code.I figure that's the best approach, but I am not sure how to not supply the implementation for a module, since in D there doesn't seem to be a separation of interface and implementation.For classes and structs, I have no idea how to leave out the implementation details.You can either use an interface or just not provide an implementation for the methods. Note that it's perfectly fine to have a method in D without an implementation even it's not abstract. This is to support the use case you have here and separate compilation.I guess you would need to list the fields on classes/structs, again that's just like C++.I have not yet seen examples or documentation explaining how to separate interface and implementation from a class or struct. Are you sure this can be done? --rt
Jan 18 2013
On 18/01/2013 08:09, Rob T wrote:On Friday, 18 January 2013 at 07:34:35 UTC, Jacob Carlborg wrote:Yes you can. I do it with a library of mine; most of it is compiled into a static lib, due to the fact that it's large enough it even slows down dmd to the point of being irritating. I maintain the .di file(s) semi separately by hand at the moment. So take your library, compile it to a static lib with: dmd -lib -ofmyStatic.lib 1.d 2.d 3.d The static lib will (obviously) contain object code for anything which is immediately compilable. Then generate you .di files (you might need to xp with this, it's been ages since I worked it out) dmd -c -o- -HdlibImportsDir 1.d Then edit your .di in libImportsDir\1.di and delete any of the implementation that you don't want exposed. Client apps use the .di files and link to the static lib. If you leave an implementation in the .di I think that takes precedence over the static lib; but I've not tested that. Generating the .di files for a large project is a pain in the ass though, so I've got a fairly sophisticated bunch of powershell scripts to handle it all and at some point I'll write my own .di generator that will use specially formatted comments to control what stays & what gets chucked, if that doesn't get added to dmd before I get off my back side. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.ukYou cannot both have CTFE/inlining/templates and hide the source code. It's the same as in C++.Yes I am aware of that limitation, nothing can be done except lose the flexibility of templates and so forth, or keep it and expose the source code.I figure that's the best approach, but I am not sure how to not supply the implementation for a module, since in D there doesn't seem to be a separation of interface and implementation.For classes and structs, I have no idea how to leave out the implementation details.You can either use an interface or just not provide an implementation for the methods. Note that it's perfectly fine to have a method in D without an implementation even it's not abstract. This is to support the use case you have here and separate compilation.I guess you would need to list the fields on classes/structs, again that's just like C++.I have not yet seen examples or documentation explaining how to separate interface and implementation from a class or struct. Are you sure this can be done? --rt
Jan 18 2013
On 2013-01-18 09:09, Rob T wrote:I have not yet seen examples or documentation explaining how to separate interface and implementation from a class or struct. Are you sure this can be done?Yes, it's supposed to work. Just create a class as you normally would and compile it as a library. Then create a di file with the same content except for the implementation of the methods are removed. Create an application that imports the di file and links with the library. // foo.d module foo; import std.stdio; class Foo { void foo () { writeln("Foo.foo"); } } // foo.di module foo; class Foo { void foo (); } // main.d module main; import foo; void main () { auto foo = new Foo; foo.foo(); } $ dmd -lib foo.d $ rm foo.d $ mv foo.a libfoo.a $ dmd main.d -L-lfoo -L-L. $ ./main Foo.foo You can try and remove the linker flags when compiling the application, then you'll get undefined symbols: "_D3foo3Foo7__ClassZ" -- /Jacob Carlborg
Jan 18 2013