www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - extern (D)?

reply "Rob T" <alanb ucora.com> writes:
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
next sibling parent reply Justin Whear <justin economicmodeling.com> writes:
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?
 
 --rt
You can use "extern(D)" or simply "extern"; this is described here: http://dlang.org/attribute.html#linkage Justin
Jan 17 2013
next sibling parent "Rob T" <alanb ucora.com> writes:
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

 Justin
So there is an extern (D), excellent! Slightly embarrassed I didn't find this for myself. --rt
Jan 17 2013
prev sibling parent Johannes Pfau <nospam example.com> writes:
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
 
 Justin
BTW: 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
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
parent reply "Rob T" <alanb ucora.com> writes:
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
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
parent "Rob T" <alanb ucora.com> writes:
On Friday, 18 January 2013 at 04:46:46 UTC, Andrej Mitrovic wrote:
 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.
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. --rt
Jan 18 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
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
parent reply "Rob T" <alanb ucora.com> writes:
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.
 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 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.
 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
next sibling parent Simon <s.d.hammett gmail.com> writes:
On 18/01/2013 08:09, Rob T wrote:
 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.
 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 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.
 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
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.uk
Jan 18 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
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