The Overall Picture

[Previous] [Next]

To fully understand how DLLs work and how you and the system use DLLs, let's start out by examining the whole picture. Figure 19-1 summarizes how the components fit together.

For now, we'll concentrate on how executable and DLL modules implicitly link to one another. Implicit linking is by far the most common type of linking. Windows also supports explicit linking (which we'll discuss in Chapter 20).

As you can see in Figure 19-1, several files and components come into play when a module (such as an executable file) makes use of functions and variables in a DLL. To simplify the discussion, I'll refer to "executable modules" as importing functions and variables from a DLL and "DLL modules" as exporting functions and variables for an executable module. However, be aware that DLL modules can (and often do) import functions and variables that are contained in other DLL modules.

click to view at full size.

Figure 19-1. How a DLL is created and implicitly linked by an application

To build an executable module that imports functions and variables from a DLL module, you must first build the DLL module. Then you can build the executable module.

Building a DLL requires the following steps:

  1. You must first create a header file, which contains the function prototypes, structures, and symbols that you want to export from the DLL. This header file is included by all of your DLL's source code modules to help build the DLL. As you'll see later, this same header file is required when you build an executable module (or modules) that uses the functions and variables contained in your DLL.
  2. You create the C/C++ source code module (or modules) that implements the functions and variables that you want in the DLL module. Since these source code modules are not required to build an executable module, the DLL company's source code can remain a company secret.
  3. Building the DLL module causes the compiler to process each source code module, producing an .obj module (one .obj module per source code module).
  4. After all of the .obj modules are created, the linker combines the contents of all the .obj modules and produces a single DLL image file. This image file (or module) contains all the binary code and global/static data variables for the DLL. This file is required in order to execute the executable module.
  5. If the linker detects that the DLL's source code module exports at least one function or variable, the linker also produces a single .lib file. This .lib file is small because it contains no functions or variables. It simply lists all the exported function and variable symbol names. This file is required in order to build the executable module.

Once you build the DLL module, you can build the executable module. These steps are

  1. In all of the source modules that reference functions, variables, data structures, or symbols, you must include the header file created by the DLL developer.
  2. You create the C/C++ source code module (or modules) that implements the functions and variables that you want in the executable module. The code can, of course, reference functions and variables defined in the DLL's header file.
  3. Building the executable module causes the compiler to process each source code module, producing an .obj module (one .obj module per source code module).
  4. After all of the .obj modules are created, the linker combines the contents of all the .obj modules and produces a single executable image file. This image file (or module) contains all the binary code and global/static data variables for the executable. The executable module also contains an import section that lists all the DLL module names required by this executable. (See Chapter 17 for more on sections.) In addition, for each DLL name listed, the section indicates which function and variable symbols are referenced by the executable's binary code. The operating system loader parses the import section, as you'll see in a moment.

Once the DLL and the executable modules are built, a process can execute. When you attempt to run the executable module, the operating system's loader performs the following steps:

  1. The loader creates a virtual address space for the new process. The executable module is mapped into the new process's address space. The loader parses the executable module's import section. For every DLL name listed in the section, the loader locates the DLL module on the user's system and maps that DLL into the process's address space. Note that since a DLL module can import functions and variables from another DLL module, a DLL module might have its own import section. To fully initialize a process, the loader parses every module's import section and maps all required DLL modules into the process's address space. As you can see, initializing a process can be time consuming.

Once the executable module and all of the DLL modules have been mapped into the process's address space, the process's primary thread can start executing and the application can run. The next few sections go into the process in further detail.



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net