DLL Review

Before we get too deeply involved in ISAPI specifics, a brief review of dynamic-link libraries (DLLs) might be helpful. Understanding DLLs is critical to understanding ISAPI DLLs.

Years ago, before Windows became popular with programmers who needed to expose some functionality to other programmers, the only option was to send object files (files with an .obj extension) or library files (files with an .lib extension). This was not an ideal solution because the functionality was then locked in at link time. If a new version of the object or library files became available, the only option was to relink the application program with the new files. In addition, if many programs required the same functionality (a common occurrence), the object code needed to be linked into each program. And when a new version became available, each program needed to be relinked. To further add to these limitations, the code linked into each and every program added to the size of each executable.

DLLs were an improvement on this method of functionality sharing. These files with a .dll extension contain functions that are made available, or exported, in a way that allows other programs to get to them. If you have a program that links to a DLL and a new version of the DLL becomes available, dropping in the new DLL is easy, and the new functionality will be availablepresuming there is a way for the application program to access that functionality. This is the ideal solution; in the real world, there are many ways this can go awry. See Appendix A for some examples of possible problems.

In addition to the DLL files, vendors commonly send library files to developers. These files are linked into the application in the same way the old-fashioned MS-DOS library files were linked in but with an important difference. Library files do not contain the actual functionality but rather the code neededat load timeto dynamically link in the code from the DLL. These libraries are called import libraries.

NOTE
Microsoft Visual C++ has new options that allow for delayed loading of DLLs, making some of the following discussion less critical. Nonetheless, it is important to understand these concepts, even if it is just to get the delayed loading allowed by the compiler to work.

This DLL model was a vast improvement over the old MS-DOS model of distributing object code that needed to be linked into an application. Now bug fixes and some types of enhancements could be added to a system without requiring changes to the executable programs. Multiple executable files could also share the same DLL, thus cutting down on the amount of code lying around on the hard disk. One problem remained: if a DLL referenced in the import library that linked into the application was not present, the application would fail to load, returning a message like the one in Figure 10-3.

The solution to this problem is the use of two function calls: LoadLibrary and GetProcAddress . These functions allow an application to explicitly request that a DLL be loaded at run time and to get a function pointer from the loaded DLL, respectively. LoadLibrary takes a single parameter, a pointer to a string containing the name of the DLL, optionally with a full or relative path name. Simply calling LoadLibrary with the name of the DLL will cause Windows 2000 to search for the DLL according to the rules spelled out in the Windows SDK documentation. If LoadLibrary fails, it returns NULL, and the reason for the failure can be retrieved using GetLastError.

GetProcAddress takes two parameters: the handle returned by a successful call to LoadLibrary and a pointer to a string containing the name of the function whose pointer should be returned. If GetProcAddress cannot find the function, it returns NULL. The name of the function is case-sensitive and must exactly match the name that is exported by the DLL. Note that in general, the name must be a standard, "undecorated" name. In a C++ program, function names are commonly decorated , or exported with prefixes or suffixes used by the linker to handle problems such as function overloading. This function decoration makes it difficult, though not impossible , to properly load these functions. All functions exported by the examples in this book are declared using an external "C" declaration, meaning the name is not altered when exported.

This run-time linking allows several additional benefits over compile-time linking using standard .lib files and load-time linking using import libraries and DLLs. The first benefit is that if the function involved is not present, an application can degrade gracefully. Thus, rather than receiving a message like the one in Figure 10-3, the user can be presented with the options available, perhaps including the option to continue to run the application in a degraded state. A second benefit is that a program using LoadLibrary can even specify exactly where the DLL should be loaded from, eliminating some of the craziness that can occur when two programs load different library files with the same name but with different functionality. Finally, as in IIS, the behavior of the application can be modified at run time, with the application decidingbased on values in a configuration file or the registryexactly what DLL to load for a given bit of functionality and possibly (though not in IIS) what function should be called.

click to view at full size.

Figure 10-3 The error message that appears when the required DLL is not present.



Inside Server-Based Applications
Inside Server-Based Applications (DV-MPS General)
ISBN: 1572318171
EAN: 2147483647
Year: 1999
Pages: 91

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