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