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 provided by API.dll you must statically link against 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 or libapi.a (names are case insensitive).
After you have statically linked your application with the import library and you run your application, here is what happens:
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 the exported routines must be listed explicitly in a definition file (see The Definition File).