Emulating DLL

Ethan gooberman at gmail.com
Wed Mar 20 14:27:54 UTC 2019


On Tuesday, 19 March 2019 at 19:50:15 UTC, Craig wrote:
> For example, with windows I could simply compile to a dll then 
> extract the code, or just use LoadLibrary and it effectively 
> does all the work(steps 1 & 2 & 3).

LoadLibrary performs steps 1 and part of step 2. The DllMain 
function of a library is called separately by Windows for each 
thread in your system, which is where the bulk of step 2 is 
handled. Step 3 isn't handled at all by LoadLibrary, and is 
instead entirely up to you to deal with via the GetProcAddress 
function.

If you want DLLs to operate in that step 1-2-3 manner, then the 
compiler can generate a static library that handles that all for 
you. But, as you might expect, that removes the hot reloading 
capability as that is all handled before WinMain is entered.

If you expect hot reloading to work without effort, you're going 
to have to compile your DLLs with -betterC. The D Runtime is not 
yet in a standalone DLL (unless I've missed an announcement over 
the last couple of months). Each DLL you build will require the D 
runtime to be embedded. Things get really tricky from there.

If you ever use your DLL for more than calling functions with 
basic types, or value aggregates (structs) containing basic 
types, then be aware that without -betterC that there is 
potential for the moduleinfo and typeinfo systems to go a bit 
screwy. Especially once druntime lives in its own DLL, as 
druntime expects those systems to be initialised once at startup. 
POSIX libraries will have the same issues, but I have nod had a 
need to investigate further over the last few months.

> LoadLibrary is not portable though and seems excessive to do 
> something that should be rather simple unless there is 
> something I'm missing that has to be done that is complex.

LoadLibrary is the equivalent to dlopen on POSIX systems, with 
one very important difference: Windows does not provide lazy 
symbol evaluation. As such, extra work is required to handle 
that. The average usecase is covered by the mentioned static lib, 
but any hot reloading is handled in a custom manner by every 
Windows codebase you'll encounter.

The static lib I mention, in fact, redirects every cross-DLL call 
to a jump table. And cross-DLL data sharing gets hairy in 
Windows. Function parameters aren't a problem, but Windows 
explicitly disallows thread local variables to cross the DLL 
boundary for example (even if you expose it for export and 
perform a symbol lookup, it won't work and you'll get garbage 
back).

As I said, it's not a simple thing by any means. My work has 
attempted to hide all that complexity by boiling it all down to 
"include these headers/modules, link this lib, and get on with 
life". If you find the resulting code too complex (and I freely 
admit that I haven't got the integration in to as foolproof a 
manner as I am aiming for) then very definitely read through the 
presentations to get a clear idea of why something that should be 
so simple really isn't.


More information about the Digitalmars-d-learn mailing list