Introduction to Dynamic Link Libraries DLLs (GNAT User’s Guide for Native Platforms)

#### 7.4.8.6 Introduction to Dynamic Link Libraries (DLLs) ¶

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 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.dll.a`, `libapi.dll.a`, `libAPI.a` or `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:

- Your application is loaded into memory.
- The DLL `API.dll` is mapped into the address space of your application. This means that:
  - The DLL uses the stack of the calling thread.
  - The DLL uses the virtual address space of the calling process.
  - The DLL allocates memory from the virtual address space of the calling process.
  - Handles (pointers) can be safely exchanged between routines in the DLL routines and routines in the application using the DLL.
- The entries in the jump table (from the import library `libAPI.dll.a` or `API.lib` or 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`.
- If present 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 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 occurs and the application will run incorrectly. Hence, when possible, you should always use and build relocatable DLLs. Both relocatable and non-relocatable DLLs are supported by GNAT. Note that the `-s` linker switch (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).