Linux – Shared Libraries: Windows vs Linux method

linuxshared-librarieswindows

I have a quick question about Windows shared libraries (DLLs) vs Linux shared libraries (SOs).

Why is it that when you create a Windows DLL it requires the client program to also link against a static library (.lib file), but applications created in Linux does not require any linking against such static library.

Does it have anything to do with code relocation and the like? Thanks.

Best Answer

Why is it that when you create a Windows DLL it requires the client program to also link against a static library (.lib file), but applications created in Linux does not require any linking against such static library.

This is a historic design decision made by Microsoft so that the linker could add DLL references into an executable without having a particular version of the DLL being present at link time. The reason for this was, that there always have been different versions of Windows around, with different versions of DLLs. Also at that time Microsoft was cooperating with IBM on OS/2 and the plan was, that Windows programs could be executed on OS/2 as well. Well, Microsoft decided to "backstab" OS/2, by rolling their own professional grade OS, based on the NT kernel. But this meant, that for development you wanted developers to be able to link against system DLLs, without having all the different variants of the DLL available. Instead a dynamic linkage "template" would have been used for creating both the DLL and the executables (both being in the PE format), which are these particular .lib files, which are not libraries at all, but merely symbol and ordinal tables (this is a little known fact, but PE binary symbols can be loaded not only by a string identifier, but also by a integer number, the so called ordinal).

A side effect of ordinals is, that they allow to hide the human readable symbols, so that you could make use of the DLL only if you knew the ordinal ←→ function relationship.

In Unix the tradition was, "you build it on the system you're going to run it on", or "you have all the target system files in place". So there was never an incentive so separate library and linkage information. Technically the same would work for DLLs, too. PEs can export a symbol and relocation table, which DLLs do, and a linker could grab all the information it requires from that, just fine.

If you were to hide symbols with Unix shared objects, you'd normally do this by using a single struct with all the function pointers in it, and only exporting a global constant instance of this struct by name, which contains a lot of not explicitly named pointers. You could do exactly the same with Windows DLLs, though.

TL;DR: The reason for this is not a technical one, but a marketing and distribution decision one.