Modern C++ Lamentations

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Jan 3 19:36:52 UTC 2019


On Thursday, January 3, 2019 12:19:59 PM MST Manu via Digitalmars-d wrote:
> On Thu, Jan 3, 2019 at 5:50 AM Jonathan M Davis via Digitalmars-d
>
> <digitalmars-d at puremagic.com> wrote:
> > On Thursday, January 3, 2019 4:52:56 AM MST rjframe via Digitalmars-d 
wrote:
> > > On Tue, 01 Jan 2019 19:04:24 -0700, Jonathan M Davis wrote:
> > > > From working with dlls with C++. With dlls on Windows, your program
> > > > links
> > > > against a static library associated with the dynamic library, and if
> > > > any
> > > > of the symbols are changed, the addresses change, and your program
> > > > will
> > > > be unable to load the newer version of the library without being
> > > > rebuilt
> > > > against the new version of the static library.
> > >
> > > That's not necessarily true; Windows supports "implicit linking" and
> > > "explicit linking"; for implicit linking you do need to statically
> > > link
> > > against an import library, but for explicit linking you don't even
> > > need to know the DLL's name until runtime.
> > >
> > > With explicit linking you load the library by calling LoadLibrary/
> > > LoadLibraryEx, then call GetProcAddress with the name of your desired
> > > function to get the function pointer. If you watch the filesystem for
> > > the
> > > DLL to change, you could live-update by reloading the DLL (which you
> > > typically wouldn't do outside debugging or maybe if offering plugin
> > > support).
> > >
> > > Most people just do implicit linking because it's less work. Any DLL
> > > can
> > > be loaded in both ways, though if there's a DllMain there may be
> > > problems
> > > if the library author doesn't support both methods; for implicit
> > > linking,
> > > DllMain is run before the program entry point, but for explicit
> > > linking
> > > its called by LoadLibrary in the context of the thread that calls it.
> >
> > *nix has the same distinction. It's a fundamentally different situation
> > from linking your executable against the library. You're really
> > dynamically loading rather than dynamically linking (though
> > unfortunately, the terminology for the two is not particularly
> > distinct, and they're often referred to the same way even though
> > they're completely different). Loading libraries that way is what you
> > do when you do stuff like plugins, because those aren't known when you
> > build your program. But it makes a lot less sense as an alternative to
> > linking your program against the library if you don't actually need to
> > load the library like that. The COFF vs OMF mess on Windows makes it
> > make slightly more sense on Windows (at least with D, where dmd uses
> > OMF by default, unlike most of the C/C++ world at this point), because
> > then it doesn't matter whether COFF or OMF was used (e.g. IIRC,
> > Derelict is designed to be loaded that way for that reason), but in
> > general, it's an unnecessarily complicated way to use a library. And if
> > Windows' eccentricities make it more desirable than it is on *nix
> > systems, then that's just yet another black mark against how Windows
> > does dynamic linking IMHO.
>
> Sorry, I don't think you know what you're talking about WRT Windows
> DLL's and import libs.
> Linking a Windows import lib is the same as `-lSharedLib.so`; it
> links(/generates) a small stub at entry that loads the DLL, and
> resolves the symbols in the import table to local function pointers.
> You certainly do NOT need to rebuild your exe if the DLL is updated,
> assuming no breaking changes to the ABI.
> The import lib includes little stub's for the import functions that
> call through the resolved pointer into the DLL. It's nothing more than
> a convenience, and it's also possible to *generate* an import lib from
> a .dll, which is effectively identical to linking against a .so.

>From the last time I worked with Windows dlls, I remember quite distinctly
that doing anything like adding a symbol to the library meant that it was
incompatible with executables previously built with it (which is not true
for shared libraries on *nix - they only break if the ABI for the existing
symbols changes). So, if that's not the case, I don't know what we were
doing wrong, but I have an extremely sour taste in my mouth from dealing
with Windows dlls. It was my experience that Linux stuff generally just
worked, whereas we kept having to deal with junk on Windows to make them
work (e.g. adding special attributes to functions just so that they would be
exported), and I absolutely hated it. I have nothing good to say about dlls
on Windows. It's quite possible that some of it isn't as bad if you know
more about it than the team I was working on did, but it was one part of why
making our libraries cross-platform was not at all fun.

- Jonathan M Davis





More information about the Digitalmars-d mailing list