writing a run time dll the application loads the dll using loadlibrary() or loadlibraryex(). the...

23
Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system to locate the DLL. Two DLLs that have the same base file name and extension but are found in different directories are not considered to be the same DLL. The operating system calls the entry-point function DllMain() whenever a process or a thread loads or unloads the DLL. If the system cannot find the DLL or if the entry-point function returns FALSE, LoadLibrary() or LoadLibraryEx() returns NULL.

Upload: hubert-armstrong

Post on 05-Jan-2016

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Writing a Run Time DLL

• The application loads the DLL using LoadLibrary() or LoadLibraryEx().

• The standard search sequence is used by the operating system to locate the DLL.

• Two DLLs that have the same base file name and extension but are found in different directories are not considered to be the same DLL.

• The operating system calls the entry-point function DllMain() whenever a process or a thread loads or unloads the DLL.

• If the system cannot find the DLL or if the entry-point function returns FALSE, LoadLibrary() or LoadLibraryEx() returns NULL.

Page 2: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Writing a Run Time DLL

• The process can use GetProcAddress() to get the address of an exported function in the DLL using a DLL module handle returned by either LoadLibrary(), LoadLibraryEx().

• Once the application has the address of the DLL function it can use a pointer to call the function.

• When the DLL module is no longer needed, the process can call FreeLibrary() or FreeLibraryAndExitThread().

Page 3: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Writing a Run Time DLL

• Writing a Run Time DLL in Visual C++ requires you to add a definition file, a .def file, to export the functions inside the DLL.

Page 4: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Advantages of Run-time DLL

• It enables the application to continue running even if a DLL is not available. For example, the process could notify the user of the error and have the user specify another path to the DLL.

• To improve startup performance, an application can implicitly link to those DLLs needed immediately after loading and wait to explicitly link to the other DLLs when they are needed.

Page 5: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Advantages of Run-time DLL

• The name of the DLL might not be available at compile time and thus the application might need to obtain the name of the DLL and the exported functions from a configuration file.

• Explicit linking eliminates the need to link the application with an import library. If changes in the DLL cause the export ordinals to change, applications using explicit linking do not have to relink, whereas applications using implicit linking must relink to the new import library.

Page 6: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Disadvantage of Run Time DLL

• Using a Run Time DLL forces the programmer to explicitly load the DLL as part of the code.

• Alternative method is to write a Load Time DLL.

Page 7: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Load Time Dynamic Linking

• A Load Time DLL is said to be linked implicitly to the application whereas a Run Time DLL is linked explicitly, hence the terms implicit and explicit linking.

• Implicit linking occurs at compile time when an application’s code makes a reference to an exported DLL function.

• When the source code for the application is compiled, the call to the DLL function translates to an external function reference in the object code.

• To resolve this external reference, the application must link with the import library (.LIB file) that is produced when the DLL is built.

• In the VC++ IDE before compiling the application one specifies the import library in the Project | Settings Dialog on the Link tab.

Page 8: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Load Time Dynamic Linking

• It is also necessary to identify the DLL functions used by the application as being imported functions.

• Do this by listing, at the top of the source file, the DLL functions being called and placing __declspec(dllimport) to the left of each of the DLL function names.

• You can then directly make a call to the functions of the DLL by calling them just like normal functions.

• After compiling the project, copy the Load Time DLL to the directory in which the application is present and run the application as normal.

Page 9: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Load Time Dynamic Linking

• When the application implicitly links to the DLL it looks just like static linking. However the library that the application links to does not contain the DLL code.

• The import library only contains information about the exported symbols from the DLL and no actual code that helps the linker resolve any function calls made to the DLL.

• If the linker finds the function export information in a lib file (import library), it assumes that the code for that function exists in a DLL, and to resolve references to that function the linker simply adds information to the final executable file that can be used by the system loader when the process starts.

• These are known as stubs, i.e. function references that are used during execution time to find the DLL functions. Hence it is still Dynamic Linking. As the process is loaded into Ram, the loader modifies the executable code of the process to point to DLL functions wherever a reference to them is made.

Page 10: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Load Time Dynamic Linking

When the system starts a program that uses load-time dynamic linking, it uses the information in the file to locate the names of the required DLL(s).

Following search sequence will be used to locate DLLs.1. The directory from which the application loaded. 2. The current directory. 3. The Windows system directory. Use the GetSystemDirectory function to get

the path of this directory. 4. The 16-bit Windows system directory. There is no function that obtains the

path of this directory, but it is searched. The name of this directory is System. 5. The Windows directory. Use the GetWindowsDirectory function to get the

path of this directory. 6. The directories that are listed in the PATH environment variable.

The DLL is mapped into the virtual address space of the process during its initialization and is loaded into physical memory only when needed.

Page 11: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Using Load Time Loading

Add a new “Win32 Console Application” project with name “UsingLoadTimeDLL” .

Choose an empty project

Using Project->Dependencies, add the dependence to LoadTimeDLL.

Add a new file named “UsingLoadTimeDLL.cpp”.

Add code shown below to “UsingLoadTimeDLL.cpp”

Page 12: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Using Load Time Loading ( Contd … )

UsingLoadTimeDLL.cpp

// Using LoadTimeDlls functionality by importing header file. // Don't define LOAD_TIME_DLL_EXPORTS symbol. Absence of this// symbol makes the __declspec(dllimport) visible to this file and hence // forces the compiler to fetch the definition form the DLL.

#include “../LoadTimeDLL/LoadTimeDLL.h”

int main()

{// You can directly make a call to exported functions of the load time

DLL.// Call a function of the Load time loaded DLL.SayLoadTimeDLL();return 0 ;

}

Page 13: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Using A Load Time DLL ( Contd … )LoadTimeDLL.h

//Add the include guards to protect from cyclic an redundant inclusions#ifndef _LOAD_TIME_DLL_H#define _LOAD_TIME_DLL_H #ifdef LOAD_TIME_DLL_EXPORTS// This is syntax that has to be followed to export a function that can be used// from other module, which loaded this dll. “__declspec(dllexport)” tells the// compiler to export the definition of this function.extern __declspec(dllexport) void SayLoadTimeDLL() ;#else// This is syntax that has to be visible for the module that uses this function.// “__declspec(dllimport)” tells the compiler to bring the definition of this// function from a DLL.extern __declspec(dllimport) void SayLoadTimeDLL() ;#endif #endif

Page 14: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Using Load Time Loading ( Contd … )

Compile the project.

Copy the LoadTimeDLL.dll to the directory in which UsingLoadTimeDLL.exe presents.

Run UsingLoadTimeDLL.exe. This will pop up a message box saying “I am a load time DLL”.

Page 15: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Dynamic Link Library Creation

–Creating Source Files–Exporting Functions

–Creating an Import Library

Page 16: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Creating A Load Time DLL

Add a new “Win32 Dynamic-Link Library” project with name “LoadTimeDLL” to the workspace “DLLsTraining”.

Choose an empty DLL project

Add a new file named “LoadTimeDLL.cpp” and “LoadTimeDLL.h” to LoadTimeDLL project.

Add code shown below to “LoadTimeDLL.cpp” and “LoadTimeDLL.h”

Page 17: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Creating A Load Time DLL ( Contd … )LoadTimeDLL.cpp

#include <windows.h> // Define the symbol LOAD_TIME_DLL_EXPORTS before including// "LoadTimeDll.h". This makes the __declspec(dllexport) visible to the// implementing .cpp file. When using this header in other modules, don’t define// this symbol. Then those modules will see __declspec(dllimport). This makes// those modules to import the function form the DLLs.

#define LOAD_TIME_DLL_EXPORTS

#include "LoadTimeDLL.h" void SayLoadTimeDLL() {

MessageBox(NULL, TEXT(“Information"), TEXT("I am a load time DLL"),MB_OK);}

Page 18: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Exporting Load Time DLL FunctionsLoadTimeDLL.h

//Add the include guards to protect from cyclic an redundant inclusions#ifndef _LOAD_TIME_DLL_H#define _LOAD_TIME_DLL_H #ifdef LOAD_TIME_DLL_EXPORTS// This is syntax that has to be followed to export a function that can be used// from other module, which loaded this dll. “__declspec(dllexport)” tells the// compiler to export the definition of this function.extern __declspec(dllexport) void SayLoadTimeDLL() ;#else// This is syntax that has to be visible for the module that uses this function.// “__declspec(dllimport)” tells the compiler to bring the definition of this// function from a DLL.extern __declspec(dllimport) void SayLoadTimeDLL() ;#endif #endif

Page 19: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Creating A Load Time DLL ( Contd … )

Compile the project LoadTimeDLL. The out put would be:

--------------------Configuration: LoadTimeDLL - Win32 Debug--------------------

Compiling...

LoadTimeDLL.cpp

Linking...

Creating library Debug/LoadTimeDLL.lib and object Debug/LoadTimeDLL.exp

LoadTimeDLL.dll - 0 error(s), 0 warning(s)

If the generation of “LoadTimeDLL.lib” is absent, it means no functions were exported and DLL cannot be loaded used.

(To test change the name of the SayLoadtimeDLL to SayLoadtimeDll. Observe case.)

Page 20: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Dynamic Link Library Entry Point

The system calls the entry-point function whenever processes and threads load or unload the DLL.

Calling the Entry-Point Function

The system calls the entry-point function whenever any one of the following events occurs:

A process loads the DLL.

A process unloads the DLL.

A new thread is created in a process that has loaded the DLL.

Use DisableThreadLibraryCalls function to disable notification when threads are created.

A thread of a process that has loaded the DLL terminates normally, not using TerminateThread or TerminateProcess.

Page 21: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Dynamic Link Library Entry Point ( Contd … )

Entry-Point Function Definition

The DLL entry-point function must be declared with the standard-call calling convention.

DLL entry point can be called in following scenarios:

A process loads the DLL (DLL_PROCESS_ATTACH)

The current process creates a new thread (DLL_THREAD_ATTACH)

A thread exits normally (DLL_THREAD_DETACH)

A process unloads the DLL (DLL_PROCESS_DETACH)

Should perform only simple initialization tasks, such as setting up thread local storage (TLS), creating synchronization objects, and opening files

Page 22: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Dynamic Link Library Entry Point ( Contd … )Entry-Point Function ExampleBOOL 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: // Initialize once for each new process. Return FALSE to fail DLL load. break; case DLL_THREAD_ATTACH: // Do thread-specific initialization. break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. break; case DLL_PROCESS_DETACH: // Perform any necessary cleanup. break;

} return TRUE; // Successful DLL_PROCESS_ATTACH. }

Page 23: Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system

Dynamic Link Library Entry Point ( Contd … )

Entry-Point Function Return Value

TRUE indicates success.

FALSE indicates failure.