Jump to page: 1 2
Thread overview
extern (D)?
Jan 18, 2013
Rob T
Jan 18, 2013
Justin Whear
Jan 18, 2013
Rob T
Jan 18, 2013
Johannes Pfau
Jan 18, 2013
Andrej Mitrovic
Jan 18, 2013
Rob T
Jan 18, 2013
Andrej Mitrovic
Jan 18, 2013
Rob T
Jan 18, 2013
Jacob Carlborg
Jan 18, 2013
Rob T
Jan 18, 2013
Simon
Jan 18, 2013
Jacob Carlborg
January 18, 2013
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
January 18, 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?
> 
> --rt

You can use "extern(D)" or simply "extern";  this is described here: http://dlang.org/attribute.html#linkage

Justin
January 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.
January 18, 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
>
> Justin

So there is an extern (D), excellent! Slightly embarrassed I didn't find this for myself.

--rt
January 18, 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
January 18, 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.
January 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
January 18, 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.

>> 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
January 18, 2013
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
January 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
« First   ‹ Prev
1 2