Under Windows, when I compile C/C++ code in a DLL project in MSVC I am getting 2 files:
MyDll.dll
MyDll.lib
where as far as I understand MyDll.lib
contains some kind of pointers table indicating functions locations in the dll. When using this dll, say in an exe file, MyDll.lib
is embedded into the exe file during linkage so in runtime it "knows" where the functions are located in MyDll.dll
and can use them.
But if I compile the same code under Linux I am getting only one file MySo.so
without MySo.a
(the equivalent to lib
file in Linux) so how does an executable file under Linux knows where the functions are located in MySo.so
if nothing is embedded into it during linking?
On Linux, the equivalent of a . dll is a "dynamic shared object", or a . so. You could statically link the required libraries in your executable, but that is really not best practice.
Dynamic linking is the most common method, especially on Linux systems. Dynamic linking keeps libraries modular, so just one library can be shared between any number of applications. Modularity also allows a shared library to be updated independently of the applications that rely upon it.
They might perform better than statically linked programs if several programs use the same shared routines at the same time. By using dynamic linking, you can upgrade the routines in the shared libraries without relinking. This form of linking is the default and no additional options are needed.
Static linking produces a larger executable file than dynamic linking because it has to compile all of the library code directly into the executable. The benefit is a reduction in overhead from no longer having to call functions from a library, and anywhere from somewhat to noticeably faster load times.
The MSVC linker can link together object files (.obj) and object libraries (.lib) to produce an .EXE or a .DLL.
To link with a DLL, the process in MSVC is to use a so-called import library (.LIB) that acts as a glue between the C function names and the DLL's export table (in a DLL a function can be exported by name or by ordinal - the latter was often used for undocumented APIs).
However, in most cases the DLL export table has all the function names and thus the import library (.LIB) contains largely redundant information ("import function ABC -> exported function ABC", etc).
It is even possible to generate a .LIB from an existing .DLL.
Linkers on other platforms don't have this "feature" and can link with dynamic libraries directly.
On Linux, the linker (not the dynamic linker) searches through the shared libraries specified at link time and creates references to them inside the executable. When the dynamic linker loads these executables it loads the shared libraries they require into memory and resolves the symbols, which allows the binaries to be run.
MySo.a
, if created, would actually include the symbols to be linked directly into the binary instead of the "symbol lookup tables" used on Windows.
rustyx's answer explains the process on Windows more thoroughly than I can; it's been a long time since I've used Windows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With