On 12/17/2011 11:22 AM, Adam Wilson wrote:
On Sat, 17 Dec 2011 01:33:33 -0800, Walter Bright <[email protected]>
wrote:

On 12/16/2011 9:01 PM, Adam Wilson wrote:
On Fri, 16 Dec 2011 01:34:32 -0800, Walter Bright <[email protected]>
wrote:

On 12/14/2011 11:41 AM, Adam Wilson wrote:
Hello Everyone,

I want to start this conversation by pointing out that I come from a C/C++/C#
background and my ideas and frustrations in this post will be colored by that
history.

When I first approached D, the idea of an 'export' confused me. I've since
figured out, at least in libraries, that in C# terms D's 'export' means
'public'.

I'm not too familiar with C#'s public, but what D 'export' means is a function
is an entry point for a DLL. In the Windows world, that means it gets an extra
level of indirection when calling it, and it corresponds to:

__declspec(export)

in Windows compilers.

Huh, I didn't know that. It makes sense though, I recall using
__declspec(dllexport) in MSVC and hating the unwieldy syntax. Does it perform a
similar function on other OS'es?

No, as such magic isn't necessary. Any public symbol will be automatically
accessible from a shared library.

So my understanding then is that, for dynamic libs on OS'es like Linux/OSX, DI
files also need to include members marked public?

The member function will be called through the vtbl[]. But for the compiler to know that member even exists, and where it is in the vtbl[], it needs to be in the .di file.

And how does the compiler
treat the export keyword on systems that don't need it? I am assuming they are
treated as publics?

Yes.


C#'s public means "this function can be used anyone, including other libraries
or executables", which according to the D docs, is what D's export means. C#
also has 'protected' and 'internal protected'. 'protected' is available to any
subclass, even those outside of the library, and 'internal protected' is only
available to subclasses within the same library.

It's actually quite a useful to have that distinction. For example, in WPF you
end up subclassing the system classes (which are in separate DLL's) repeatedly
and it is an encouraged pattern to extend existing functionality with your own.
The reason I went with the syntax I did is that it doesn't add any new keywords
and is, I think, even more clear about the programmers intentionality than C#'s
scoping model. If 'export' really is just the equivalent of
__declspec(dllexport) then it makes even more sense as an attribute and not a
scope in it's own right.

However, this raise a problem, specifically, how do I export a
protected member from a dynamic library?

Do you mean how does one directly call a protected function inside a DLL from
outside that DLL, without going through the virtual table?

What I am after is a member that can be overridden in a subclass outside of the
DLL but is otherwise only reachable within the module it's defined in. Mr.
Carlborg's code example is spot on.

It isn't necessary to export a protected symbol in order to override it.

I see, that's a neat little trick. +1 for D!

C++ works the same way.


So for DI file generation I should
just include the protected members in the file and let the compiler sort it out?

Yes.


I know DLL's are relatively new to D so not much documentation exists about how
they work in D. I think this would be something good to document, especially the
special behaviors for Windows. I have to admit that, coming from a C# and C++
background, I've been a little confused by how the scope system works in
relation to dynamic libraries and have been shooting the dark trying to figure
it out. Thanks for the clarifications! Hopefully this lesson will become part of
the D lore surrounding dynamic libs. :-)

DLL's have been supported in D forever, but hardly anyone uses them, and sometimes they get bit rotted.

I strongly recommend Jeffrey Richter's book "Advanced Windows" for a low level and lucid explanation of how DLLs work.

Reply via email to