Your browser doesn't support JavaScript DLLs – Windows Programming

DLLs

A DLL is Microsoft’s way of implementing a code library that multiple programs can use. A DLL can contain almost anything that can be compiled into a normal Windows program, but unlike executable programs, DLL files can’t be run directly and must be called upon by other code. These libraries usually have the file extension DLL, OCX, or DRV. There are several advantages to using DLLs –

  • DLLs can reduce the duplication of code when a different program uses the same code library
  • Easy deployment and installation. For instance, when multiple programs use the same DLL, those programs will all benefit from the same update or fix.
  • DLLs help with modular programming enabling a program to be split into smaller tasks.

Implementing a DLL

Any function or data within a DLL that will be accessed by another program or DLL must be exported. Likewise, any function or data imported from a DLL must be imported. Any code for import or export is declared using the _declspec keyword followed by storage-class attributes in parentheses (dllimport and dllexport) and then the function name.

For example, to export a function from a DLL:

__declspec(dllexport) void functionname()

To import the same function into an application:

__declspec(dllimport) void functionname()

A simple DLL

The example below illustrates a simple DLL file consisting of one function and a MessageBox routine. When a DLL project is compiled, it typically produces two files: a .dll file containing the executable code and a .lib import library used by the linker. The .dll file must be located where Windows can find it at runtime. By default, Windows searches the application’s directory first, followed by the system directories (such as System32), and then other directories included in the DLL search path, such as those specified by the PATH environment variable.

//file name exampleDLL.lib
#include <windows.h>
extern "C" __declspec(dllexport) void msgfunct()
{
MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}

The optional declaration extern “C” enables a library to be shared between C and C++. This is necessary so that the C++ compiler does not add any extra mangling information during compilation

Linking to a DLL

There are two ways to load a DLL: implicit linking and explicit linking

Implicit linking is when the operating system automatically loads a DLL when the executable file is loaded. The client program can then call exported functions in the DLL in the same way as functions that are part of the executable. To use implicit linking, the client program must link against the DLL’s import library (.lib file). The .lib file must be placed in a location where the linker can find it, such as the project directory, a library folder configured in the Visual C++ project settings, or a directory specified in the linker’s library search path. The .lib file is only required when building the application and does not need to be distributed with the final executable.

In Visual C++, linking to the import library can be done through Project Properties → Linker → Input → Additional Dependencies, or by adding a #pragma comment(lib, "MyDLL.lib") directive in the source code. The corresponding .dll file must then be placed in a directory where Windows can locate it when the application runs.

The following example illustrates a simple DLL file that contains a simple message box function. When imported and executed, the called function displays a messagebox.

//example console exe
#pragma comment(lib, "exampleDLL.lib")
extern "C" __declspec(dllimport) void msgfunct();
int main(int argc, char* argv[])
{
msgfunct();
return 0;
}


Explicit linking is when the operating system loads a DLL at runtime rather than when the executable is started. The application is responsible for loading the DLL using the LoadLibrary() function and releasing it using FreeLibrary() when it is no longer required. Access to functions inside the DLL is obtained at runtime using GetProcAddress(), which returns the memory address of the exported function. This address is then stored in a function pointer, allowing the program to call the DLL function. Explicit linking does not require the DLL import library (.lib) file because the connection to the DLL is made while the program is running.

The following example illustrates a simple console exe file that imports and calls a simple dll function, from the dll file exampleDLL.dll (above)

#include <windows.h>
typedef VOID (*DLLPROC) ();
DLLPROC HelloWorld;
int main(int argc, char* argv[])
{
DLLPROC HelloWorld;
HINSTANCE hInstLibrary = LoadLibrary("exampleDLL.dll");
if (hInstLibrary)
{
HelloWorld = (DLLPROC) GetProcAddress(hInstLibrary, "msgfunct");
if (HelloWorld != NULL)
HelloWorld ();
FreeLibrary(hInstLibrary);
}
}

DllMain

The DllMain function is an optional entry point for a dynamic-link library (DLL). It is called automatically by the Windows loader whenever a DLL is loaded into or removed from a process, and when threads are created or terminated within that process. It is used to perform simple initialization when the DLL starts and cleanup tasks before the DLL is unloaded. The function receives a reason code (fdwReason) that identifies why it was called.

The syntax is

BOOL WINAPI DllMain(HINSTANCE hinstDLL,    // handle to DLL module
DWORD fdwReason,       // reason for calling function
LPVOID lpReserved )    // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Occurs when a DLL is being loaded into memory for each new process. Return FALSE if DLL failed to load.
break;
case DLL_THREAD_ATTACH:
// occurs when current process is creating a new thread
break;
case DLL_THREAD_DETACH:
// occurs when a thread is exits cleanly
break;
case DLL_PROCESS_DETACH:
// Occurs DLL is being unloaded from memory
break;
}
return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

Return Value

Returns TRUE if it succeeds or FALSE if initialisation fails
For further detailed reading –
https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain