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
DllMainCRTStartupare 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).