Introduction
If you like to create modular software, you choose DLLs. Dynamic linked libraries are easy to create compared to applications. Dynamic linked library is a set of modules that contains a set of functions or other called DLLs.
In windows operating system some of the DLLs are important. They are the following - User32.dll manages user interface related tasks. The Gdi32.dll manages graphic device interface related (GDI) tasks. In DOS world, programs write directly into video memory. But, in windows layer called Graphic Device Interface (GDI) exists. The advapi32.dll manages registry related tasks. The comdlg32.dll manages the common dialog box related tasks (Example File open dialog box, file save and save as dialog box). The comctrl32.dll manages the windows common control related tasks.
The Windows DLLs are the backbone of windows operating system. The windows operating system manages the large set of system DLLs. When the windows operating system starts, the DLLs load to system memory.
Types of DLL
The windows operating system has two types of DLLs. There are the following.
- Load Time Dynamic Linking
- Run Time Dynamic Linking
The Load Time Dynamic Linking load the DLLs at the load time. When the application starts, all the required DLLs are loaded into memory in the startup time. In this method the system tries to find the DLLs in the following locations.
- The Windows System Directory
- The Windows directory
- The Application local path
- The directories listed in the path environment variables
Load Time DLLs requires LIB file and declaration file (.h), when we create application programs. We insert the header file in the application and link with the LIB file in the application project settings. The DLLs do not handle windows messages. The DLLs are simply set of functions or variables declared in the declaration file ( .h) and implemented in the implementation file(.cpp).
The run time dynamic linking tries to load DLL at run time. The LoadLibrary
function is used to load a DLL at run time. The syntax for LoadLibrary
is the following.
HINSTANCE hinst = LoadLibrary(LPCTSTR dllfilename);
If the LoadLibrary
returns success, then we use GetProcAddress
get the address of the functions. After calling DLL function we call FreeLibrary
to free the DLL library. In this run time dynamic linking, we do not load all the DLL files in the startup time. Whenever we want to load, we load and unload the DLLs.
Create Load time Win32 DLL
We already saw, that using DLLs is easy to create modular applications. In win32 Dynamic linked library project choose DLL and add support for some export symbols in second step. In that class declaration add your method and return types. When you allocate memory in the DLL file, you also deallocate it. If you deallocated from the client (like from application) it may be deallocated but we cannot be sure.
__declspec(dllimport)
tells the compiler to add some symbols for import from the DLLs. This way the __declspec(dllexport)
tells the compiler to export some symbols. In our sample program declare the three functions. The functions are to add, multiply and subtract the two values. These simple DLLs help you understand the basic DLLs functionality.
The DLL entry point is the DllMain
; the DllMain
has the following syntax.
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH:
.
.
case DLL_THREAD_ATTACH:
.
.
case DLL_THREAD_DETACH:
.
.
case DLL_PROCESS_DETACH:
.
.
}
return TRUE;
}
You copy DLL file into system directory and copy LIB file into Visual C++ Lib directory and link to lib file. In application module make sure to implement the header file. In our example file is declared in the following manner.
#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif
class WIN32DLL_API CWin32DLL {
public:
CWin32DLL(void);
int add(int a,int b);
int sub(int a,int b);
int mul(int a,int b);
};
extern WIN32DLL_API int nWin32DLL;
The class CWin32DLL
has been declared as __declspec(dllexport)
using WIN32DLL_API
. So, all the class member functions and member variables are __declspec(dllexport)
. All the member functions are declared as public
.
In our implementation file, we link and call the functions.
The run time dynamic linking in the client program are the following.
#include "stdio.h"
#include "windows.h"
typedef VOID (*MYPROC)(LPTSTR);
VOID main(VOID)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
hinstLib = LoadLibrary("win32dll.dll");
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "add");
if (fRunTimeLinkSuccess = (ProcAdd != NULL))
(ProcAdd) ("message via DLL function\n");
fFreeResult = FreeLibrary(hinstLib);
}
if (! fRunTimeLinkSuccess)
printf("message via alternative method\n");
}
Create MFC DLL
Microsoft Foundation Class (MFC) library can be used to create simplified DLLs. The MFC supports two types of DLLs. Those are the following.
- Regular DLL with MFC statically linked
- Regular DLL using shared MFC Dll
- MFC Extension DLL ( Using shared MFC DLL)
In the regular DLL with MFC statically linked, the Client may be MFC based application or Non-MFC application. Our sample program application is based on a DLL using shared MFC dll.
MFC Extension DLL has reusable classes derived from existing Microsoft foundation Classes. Extension DLL is built from Dynamic linked library version of the DLL. In MFC, regular DLLs are initialized in three ways. The DLL has a CWinApp
Object. MFC OLE initializes using MFC global AfxOleInitModule
function. The MFC Database initializes into MFC using global AfxDbInitModule
function. MFC Sockets are initialized using AfxNetInitModule
function.
Initializing the Extension DLLs is as following.
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID
lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
AfxInitExtensionModule(PROJNAMEDLL, hInstance);
new CDynLinkLibrary(dll);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
}
return 1;
}
In our example, The Dll has DrawEllipse
function. We pass the CRect
structure and CDC
to DLL. The DLL function draws the DLL with selected Blue Brush.
Benefits of DLLs
The benefits of using DLLs are the following.
- The Dynamic linked library shares the memory. So, the system performance is improving compared to using applications.
- We can build and test separately each DLL.
- We can create DLLs for different languages. Windows use C DLL, C++ DLL, Fortran DLL and PASCAL DLL etc. Even windows support some version of Smalltalk DLLs.
- We can load and unload at run time. This helps to improve application performance.
- The big software products were divided into several DLLs. The developers easily develop their application.