Dynamic D Library

Daniel Keep daniel.keep.lists at gmail.com
Fri Jul 17 00:12:51 PDT 2009



Jarrett Billingsley wrote:
> On Thu, Jul 16, 2009 at 9:30 PM, grauzone<none at example.net> wrote:
>> I know a simple counter measure: use DLLs as a container for the DDL
>> specific format. AFAIK C# does exactly the same.
> 
> Hmm!

You know, this is so obvious in retrospect.

?cookie grauzone

What we really need is a new linker that can produce "DDL-ified" DLLs
and executables.

<thinking type="out-loud" opinion="mostly-uninformed">
<![CDATA[

Let's assume someone was crazy enough to write a new linker.  One option
for output could be -dll.  This would compile the given source files
into a static library, and then embed it into a DLL.

We can arrange it so that D's shared library loading code recognises
DLLs with an embedded DDL library (perhaps a standardised export
function: ddl_getEmbeds or something).

Even better: if you do this with the new linker:

> link mymain.d dmdrt.dll phobos.dll libfoo.dll

It replaces the regular main with a stub main that starts DDL, loads the
requested DLLs via system calls, pulls the embeds out, links everything
together and THEN calls the D runtime's main (which then calls YOUR
main).  You could keep the majority of DDL in dmdrt.dll; the executable
itself would only require enough to call LoadLibrary, pull out the
embeds and get a pointer to a bootstrap function.

This way, code doesn't need to be written to use DDL; the linker takes
care of managing the difference.

The standard library's shared library loading code could then be
extended to be able to load D calls directly (ie:
shlib.load!(TypeOfFunction)("package.module.name") or somesuch).

The problem, then, is with extern(C), extern(Windows) and extern(C++)
functions.

*thinks*

We could have the linker expose those directly; they have distinct name
mangles from D functions, so it should be able to identify them.  It
could place these functions in the "standard" part of the DLL so that
they're accessible from C/C++ code.

In order for that to work, though, we'd need to init. the standard
library, GC, etc.  We can do that in DllMain IF we require that all D
DLLs *dynamically* link to the standard library.  Because we're using
system calls to load the DLLs (along with their embed payload, which is
what we're actually interested in), it should only load one copy.

If we have, for example, a C app that is using D code as plugins, each
plugin will ask the system for "dmdrt.dll" using its minimal embedded
DDL stub.  But since they're system calls, we should only get one copy.
 I'm not sure exactly how the system will share that library, though;
whether it's per-process or system-wide.

In any case, the DDL stub should be able to pull in the full DDL from
dmdrt.dll and then use that to link everything together.

The nice bonus of this is that DDL just becomes an implementation detail
AND we can say "yes, we can do DLLs in D!" even if we're only using them
to contain a DDL payload.

The one downside I can think of is that if you DID want to distribute a
D plugin for a C/C++ program, you'd also need to ship dmdrt.dll
alongside it.  Although, in that case, it probably wouldn't hurt
anything (aside from memory usage) to simply statically link the runtime
and standard library in; if the host app is C/C++, then the plugins
probably won't be able to stomp all over each other.

]]>
</thinking>



More information about the Digitalmars-d mailing list