A Dynamically Linked Library (DLL) is a library that can be shared by several applications running under Windows. A DLL can contain any number of routines and variables.
One advantage of DLLs is that you can change and enhance them without forcing all the applications that depend on them to be relinked or recompiled. However, you should be aware than all calls to DLL routines are slower since, as you will understand below, such calls are indirect.
To illustrate the remainder of this section, suppose that an application
wants to use the services of a DLL
API.dll. To use the services
API.dll you must statically link against the DLL or
an import library which contains a jump table with an entry for each
routine and variable exported by the DLL. In the Microsoft world this
import library is called
API.lib. When using GNAT this import
library is called either
libapi.a (names are case insensitive).
After you have linked your application with the DLL or the import library and you run your application, here is what happens:
API.dllis mapped into the address space of your application. This means that:
API.libor automatically created when linking against a DLL) which is part of your application are initialized with the addresses of the routines and variables in
API.dll, routines DllMain or DllMainCRTStartup are invoked. These routines typically contain the initialization code needed for the well-being of the routines and variables exported by the DLL.
There is an additional point which is worth mentioning. In the Windows world there are two kind of DLLs: relocatable and non-relocatable DLLs. Non-relocatable DLLs can only be loaded at a very specific address in the target application address space. If the addresses of two non-relocatable DLLs overlap and these happen to be used by the same application, a conflict will occur and the application will run incorrectly. Hence, when possible, it is always preferable to use and build relocatable DLLs. Both relocatable and non-relocatable DLLs are supported by GNAT. Note that the `-s' linker option (see GNU Linker User’s Guide) removes the debugging symbols from the DLL but the DLL can still be relocated.
As a side note, an interesting difference between Microsoft DLLs and Unix shared libraries, is the fact that on most Unix systems all public routines are exported by default in a Unix shared library, while under Windows it is possible (but not required) to list exported routines in a definition file (see The Definition File).