DYNAMIC LINK LIBRARIES

DLL

   Basic building block of Windows;

   Provides reusable code;

   Can be shared by many applications simultaneously;

   Windows itself is a set of DLLs.

A file containing functions that can be called    
by other programs or DLLs.

Provides a way for a process to call a  
function that is not part of its executable code.

Difference Between Static and Dynamic Linking


 
 

Two methods of calling a function in a DLL:

   Load-time dynamic linking (early binding)

   Run-time dynamic linking (late binding)

   <See Figures -- transparencies>

File extension .DLL makes the DLL implicitly available to applications.

DLL functions are not directly executable--must be called.

A DLL usually doesn't display a window or receive messages.

A DLL Can be accessed by any number of applications--

A Windows solution to problem of sharing code (and data) between 
applications.

DLL Code is loaded only once.

Provides for extending Windows--
  Add new functions in a DLL or write a new DLL.

ADVANTAGES OF DYNAMIC LINKING--

  Memory space is saved and swapping is reduced.
   (Many programs can use same DLL--only loaded once)

Functions in DLL can be changed without recompiling applications that use 
them (as long as exported DLL interface doesn't change). 

Programs written in different languages can call the same DLL functions. 

POTENTIAL DISADVANTAGES OF DYNAMIC LINKING--

The application is not self-contained. The DLL module must be present.

Changed DLL could cause other applications to not function properly.

SOME DETAILS OF DLL OPERATION--

DLLs don't have their own stack--instead use stack of calling program 
(automatic & global variables).


DLLs have their own local heap for static variables (e.g., strings)-- 
can cause problems.

 

DLL can allocate a separate memory block for each calling program's data. 

 Global blocks allocated by a DLL "belong" to the calling program. 

BUILD DETAILS--

Linker must be told that functions in a DLL are available for calling 
from another program.

For Example:

BOOL CALLBACK BlockRev(LPSTR, int);  // Defined in a DLL

In our DLL module's header file we could do the following:

#define EXPORT extern __declspec(dllexport)
                           // define EXPORT macro
EXPORT BOOL CALLBACK BlockRev(LPSTR, int); 
                           // declare as EXPORT

This will tell the linker that revstr() is exportable.




WRITING A DLL--

Most DLL's contain the function: DllMain()--like WinMain():

First function executed when DLL is loaded into memory by Windows

   Performs initialization stuff

   Runs only once (when DLL is loaded)

 int CALLBACK DllMain (HINSTANCE hInstance, 
                       DWORD  fdwReason, 
                       PVOID pvReserved);

Parameters passed to DLL from Windows:

hInstance--DLL's instance handle (for access to DLL resources, if present)

fdwReason--Value indicates why Windows is calling DllMain()

  pReserved--Reserved

DllMain() could perform initialization code (e.g., initializing static data).

DllMain() should return nonzero ==> Initialization was a success. 
0==> initialization failed --
  (Windows will not run the program using the DLL)

For most simple cases, all that DllMain() has to do is:

   return(1);


COMPILING AND USING A DLL, AN EXAMPLE--

REVSTR DLL:
Source file:  REVSTR.CPP -- provides ftn BlockRev()
Header file:  REVSTR.H--declares & exports ftn BlockRev()

DLLCALL App that uses the DLL:
Source file:  DLLCALL.CPP -- Calls the BlockRev() ftn
Header file:  DLLCALL.H -- Normal declarations
Header file:  REVSTR.H -- tells compiler about BlockRev()
       
Resources:    DLLCALL.RC

WHAT THE PROGRAM DOES: Reverses the characters in a string--

User selects "Show Strings" from DLLCALL's menu ==>
  DLLCALL's WndProc() does the following:
    gets string from resource file, 
    allocates a global memory block, 
    calls BlockRev() in the REVSTR DLL (does the reversing), 
  Displays both original and reversed strings.


RUNTIME DYNAMIC LINKING

Use:
   hLib = LoadLibrary(“dll_file_name”);                  // Load the DLL
   pFtn = GetProcessAddress(hLib, “ftn_name”);     // Get ptr to the function
   Then call the function by transferring control to its address using pFtn

Example: A Roundabout Way of Drawing a Rectangle
   Rectangle() is a function in the GDI32.DLL dynamic link library
   Can call it as shown above:

Typedef BOOL (WINAPI * PFNRECT) (HDC, int, int, int, int);
HMODULE         hLib;
PFNRECT         pfnRect;
HDC             hDC;
int             xLeft=10, yTop=10, Xright=100, yBottom=100;

hLib = LoadLibrary(“GDI32.DLL”);
pfnRect = (PFNRECT) GetProcAddress(hLib, “Rectangle”);
pfnRect(hDC, xLeft, yTop, xRight, yBottom);
FreeLibrary(hLib);