Coder Perfect

What is the difference between shared objects (.so), static libraries (.a), and dynamic link libraries (.so)?


I’ve been involved in a discussion about libraries in Linux and would like to clarify a few points.

There are two ways to use libraries while constructing an application, in my understanding (please correct me if I’m wrong, and I’ll modify my post later):

Static libraries have the obvious advantage of allowing the entire application to be self-contained, whereas dynamic libraries have the advantage of allowing the “.so” file to be replaced (for example, if it needs to be updated due to a security bug) without requiring the base application to be recompiled.

Even though they are both “.so” files, I’ve heard some folks establish a distinction between shared objects and dynamic linked libraries (DLLs). When it comes to C/C++ development on Linux or any other POSIX compliant OS (e.g., MINIX, UNIX, QNX, etc. ), is there a difference between shared objects and DLLs? One important difference, according to my sources, is that shared objects are only accessed at runtime, whereas DLLs must be launched first using the dlopen() call within the application.

Finally, I’ve heard some developers reference “shared archives,” which are, according to my understanding, static libraries that are never directly utilized by an application. Instead, other static libraries will link against the “shared archives” to extract some (but not all) of the shared archive’s functions/resources into the static library being produced.

Thank you in advance for your cooperation.

These terms were effectively erroneous terms used by a team of Windows engineers who had to learn Linux in the context in which they were supplied to me. I attempted to amend them, but the (incorrect) linguistic rules remained.

The distinction between “DLL” and “shared library” was simply a (lazy, erroneous) colloquialism in the firm where I worked at the time (Windows developers were forced to switch to Linux development, and the word stayed), according to the descriptions noted above.

Furthermore, in the instance of “shared archives,” the trailing “S” literal after the library name was a company-specific norm, not an industry-wide one.

Asked by Cloud

Solution #1

A static library (.a) is a library that can be linked directly into the final executable produced by the linker since it is contained within it. The library does not need to be installed on the system where the executable will be used.

A shared library(.so) is a library that is linked but not embedded in the final executable, so will be loaded when the executable is launched and need to be present in the system where the executable is deployed.

A dynamic link library (.dll) on Windows is similar to a shared library (.so) on Linux, however there are certain distinctions that are tied to the operating system (Windows vs Linux):

There are two types of functions that can be defined in a DLL: exported and internal. Other modules, as well as the DLL where they are defined, can call the exported functions. Internal functions are usually only meant to be invoked from within the DLL in which they are created.

Because all symbols are available to an interrogating process, a SO library under Linux does not require a separate export statement to identify exportable symbols.

Answered by aleroot

Solution #2

I’ve always assumed that DLLs and shared objects are simply different names for the same thing – DLLs on Windows, shared objects on UNIX systems, with the broad term – dynamically linked library – covering both (even the UNIX method to open is called dlopen() after ‘dynamic library’).

Although they are only linked at program starting, your assumption that they are checked against the header file is false. The header file defines prototypes that are required to compile code that utilizes the library, but the linker searches inside the library itself at link time to ensure that the functions it requires are present. At link time, the linker must locate the function bodies or an error would occur. It also does that at runtime, because the library itself may have changed since the application was generated, as you correctly point out. This is why ABI stability is so crucial in platform libraries, because changes to the ABI are what cause current programs compiled against previous versions to break.

Static libraries are simply bundles of object files straight from the compiler, just like the ones you’re producing as part of your project’s compilation, so they’re pulled in and supplied to the linker in the same way, and unwanted portions are eliminated in the same way.

Answered by Matthew Walton

Solution #3

I can go into more depth on DLLs in Windows to help my friends in *NIX-land understand what’s going on…

A Shared Object file is similar to a DLL. Both are pictures that the respective OS’s application loader can load into memory. The images are accompanied by a variety of metadata to aid linkers and loaders in making the appropriate associations and utilizing the code library.

An export table exists in Windows DLLs. The exports can be done by table position or by name (numeric). The latter way is regarded “old school” and is far more vulnerable — rebuilding the DLL and changing the position of a function in the table will result in disaster, whereas linking entry points by name poses no such problem. So, don’t think about it as a problem; just be aware that it exists if you work with “dinosaur” programs like 3rd-party vendor libs.

Windows DLLs are created by compiling and linking, just like an EXE (executable application), but unlike a SO, they are intended to be used by an application, either dynamically or via link-time binding (the reference to the SO is embedded in the application binary’s metadata, and the OS program loader will auto-load the referenced SO’s). DLLs can refer to other DLLs in the same way that SOs can refer to other SOs.

DLLs in Windows will only make specified entry points available. These are referred to as “exports.” To make a symbol externally visible (to other linkers and the dynamic loader), the developer can use a specific compiler keyword, or the exports can be listed in a module-definition file that is used at link time when the DLL is being constructed. Modern practice is to include a term to the function specification that exports the symbol name. It’s also possible to use keywords in header files to declare a symbol as one that should be imported from a DLL outside of the current compilation unit. For further information, look up the terms __declspec(dllexport) and __declspec(dllimport).

DLLs have the ability to designate a standard “upon load/unload” handler function, which is an intriguing feature. When a DLL is loaded or unloaded, it can conduct some initialization or cleanup, depending on the situation. This corresponds to a DLL serving as an object-oriented resource manager, such as a device driver or shared object interface.

When a developer wishes to use an already-built DLL, she must either use the LoadLibrary() and GetProcAddress() techniques to load the DLL and request the entry point address by name, or she must use a “export library” (*.LIB) generated by the DLL developer when she produced the DLL. DLLs are typically utilized via linking against a LIB file (which merely includes the linker metadata for the DLL’s exported entry points). Dynamic loading is usually used in program behaviour to implement “polymorphism” or “runtime configurability” (accessing add-ons or later-defined functionality, aka “plugins”).

The.LIB extension is used by Windows to refer to both standard static libraries (archives, such as POSIX *.a files) and the “export stub” libraries required to bind an application to a DLL at link time. This can be confusing at times. As a result, one should always check to see if a *.LIB file contains a *.DLL file with the same name; if not, the *.LIB file is most likely a static library archive, not binding metadata for a DLL.

Answered by JoGusto

Solution #4

Static files are copied to the application at link time, whereas shared files are only validated at link time and loaded during runtime, as you stated.

If the application desires to load shared objects at runtime on its behalf, the dlopen call is used; otherwise, shared objects are loaded automatically when the application starts. The terms DLLS are interchangeable. The dlopen was created to give processes even more fine-grained dynamic loading capabilities. You don’t have to use dlopen to open/use the DLLs; it happens automatically when the application starts.

Answered by rapadura

Solution #5

I believe there is a misunderstanding here, because header files, at least those of the.h sort required for producing source code, are not verified during link time.

The use of.h files, as well as.c/.cpp files, is limited to the compilation phase, which includes preprocessing. The header file is long gone by the time the linker gets around to dealing with things after the object code has been produced.

Answered by Raymond Jennings

Post is based on