Dynamic Link Libraries (DLLs) allow code and data to be shared among multiple applications. DLLs improve efficiency by loading a single shared copy of code into memory rather than having each application carry its own copy. DLLs export functions and variables that other applications can call via implicit or explicit linking methods. The DllMain function provides optional initialization and cleanup code that runs when a DLL is loaded or unloaded.
Dynamic Link Libraries (DLLs) allow code and data to be shared among multiple applications. DLLs improve efficiency by loading a single shared copy of code into memory rather than having each application carry its own copy. DLLs export functions and variables that other applications can call via implicit or explicit linking methods. The DllMain function provides optional initialization and cleanup code that runs when a DLL is loaded or unloaded.
Copyright:
Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online from Scribd
Dynamic Link Libraries (DLLs) allow code and data to be shared among multiple applications. DLLs improve efficiency by loading a single shared copy of code into memory rather than having each application carry its own copy. DLLs export functions and variables that other applications can call via implicit or explicit linking methods. The DllMain function provides optional initialization and cleanup code that runs when a DLL is loaded or unloaded.
Copyright:
Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online from Scribd
Outline • DLL Libraries • DllMain • Linking a DLL Dynamic-Link Libraries • DLL is a module that contain functions and data that can be used by another module (application or DLL) • It can define two kinds of functions – Exported • Intended to be called by other modules – Internal • Intended to be called only from within the DLL Dynamic-Link Libraries • Dynamic Link Libraries (DLL) are an important structural component of Microsoft Windows. • DLLs allow certain code fragments to be compiled into a single library, and to be linked to by multiple programs. – This means that only one copy of the library needs to exist, and multiple programs can share the functions and the data between them. – The difference between a DLL and a static library is that when you compile your programs, the DLL is not compiled into your executable, but instead remains a separate module. – This feature helps to keep executable size low, and also allows for a DLL to be loaded into memory only when it is needed. • The exact method of building a DLL file is dependant on the compiler you are using. – However, the way in which DLLs are programmed is universal. We will talk about how to program DLL files later. Advantages of Using DLL • Some advantages over static linking – Smaller program image – Save system memory, since multiple processes can share a single copy of the DLL – Easy to support new versions or alternative implementations – Run time decision of which version to use __declspec • The __declspec keyword is a strange new keyword that is not part of the ANSI C standard, but that most compilers will understand anyway. • __declspec allows a variety of non- standard options to be specified, that will affect the way a program runs. • Specifically, there are two __declspec identifiers that we want to discuss: __declspec(dllexport) __declspec(dllimport) __declspec - dllexport • When writing a DLL, we need to use the dllexport keyword to denote functions that are going to be available to other programs. – Functions without this keyword will only be available for use from inside the library itself. – Here is an example: __declspec(dllexport) int MyFunc1(int foo) __declspec – where to use it
• The __declspec identifier for a function
needs to be specified both in the function prototype and the function declaration, when building a DLL. __declspec – Importing a DLL • To "import" a DLL function from a regular program, we need to link to the DLL, and we need to prototype the function with the dllimport keyword as such: __declspec(dllimport) int MyFunc1(int foo); • Now the program can use the function as normal, even though the function exists in an external library. The compiler works with Windows to handle all the details for you. • If the calling (importing) client program is written in C++, it is necessary to specify the C calling convention – extern “C” _declspec(dllimport) DWORD … __declspec - Common Macro • Many people find it useful to define a single header file for their DLL, instead of maintaining one header file for building a DLL, and one header file for importing a DLL. • Here is a macro that is common in DLL creation: #ifdef BUILDING_DLL #define DLL_FUNCTION __declspec(dllexport) #else #define DLL_FUNCTION __declspec(dllimport) #endif __declspec - Common Macro • Now, to build the DLL, we need to define the BUILDING_DLL macro, and when we are importing the DLL, we don't need to use that macro. • Functions then can be prototyped as such: • DLL_FUNCTION int MyFunc1(void); • DLL_FUNCTION int MyFunc2(void); ...
• NOTE: Microsoft did not intend for this __declspec
syntax to be used. Instead the intention was that the public api of a DLL would be declared in an "exports" file. However the above syntax, despite requiring the macro to switch it back and forth, was much more convenient and is pretty much used by all software today. DllMain • When Windows links a DLL to a program, Windows calls the library's DllMain function. • This means that every DLL needs to have a DllMain function. • The DllMain function needs to be defined as such: BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD reason, LPVOID reserved) DllMain • DllMain is an optional entry point into a dynamic- link library (DLL). – When the system starts or terminates a process or thread, it calls the entry-point function for each loaded DLL using the first thread of the process. – The system also calls the entry-point function for a DLL when it is loaded or unloaded using the LoadLibrary and FreeLibrary functions. • Warning: – There are serious limits on what you can do in a DLL entry point. To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL. General template for a DllMain function BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; }
• However, if you aren't interested in any of the reasons, you can
remove the entire switch statement from your program and return TRUE. DllMain • The DllMain function doesn't need to do anything special for these cases, although some libraries will find it useful to allocate storage for each new thread or process that is being used with the library. • The DllMain function must return TRUE if the library loaded successfully, or FALSE if the library had an error and could not load. If you return FALSE, the program will pop up a warning message and crash. DllMain • The keywords "BOOL", "APIENTRY", "HINSTANCE", etc., are all defined in <windows.h>. So, you must include that file even if you don't use any Win32 API functions in your library. • APIENTRY is just a keyword that Windows uses internally. So, you don't need to worry about it. • The variable "hInstance" is the HINSTANCE handle for the library, and you can keep this and use it, or you can trash it. reason will be one of four different values: – DLL_PROCESS_ATTACH • a new program has just linked to the library for the first time. – DLL_PROCESS_DETACH • a program has unlinked the library. – DLL_THREAD_ATTACH • a thread from a program has linked to the library. – DLL_THREAD_DETACH • a thread from a program has just unlinked the library. Dynamic-Link Libraries - Linking Methods • 2 types of dynamic linking – Load-time linking (Implicit/static) • Required to link the module with the import library (.lib and .dll files) • Easier to use – Run-time linking (Explicit/dynamic) • Use LoadLibrary or LoadLibraryEx to load the DLL at run time • Use GetProcAddress function to get the addresses for the exported DLL functions • FreeLibrary – unloads the DLL Load-time linking (Implicit) • Implicit linking occurs when an application's code calls an exported DLL function. • When the source code for the calling executable is compiled or assembled, the DLL function call generates an external function reference in the object code. • To resolve this external reference, the application must link with the import library (.lib file) provided by the maker of the DLL. Load-time linking (Implicit) • The import library only contains code to load the DLL and to implement calls to functions in the DLL. • Finding an external function in an import library informs the linker that the code for that function is in a DLL. • To resolve external references to DLLs, the linker simply adds information to the executable file that tells the system where to find the DLL code when the process starts up. Load-time linking (Implicit) • When the system starts a program that contains dynamically linked references, it uses the information in the program's executable file to locate the required DLLs. • If it cannot locate the DLL, the system terminates the process and displays a dialog box that reports the error. • Otherwise, the system maps the DLL modules into the process's address space. Load-time linking (Implicit) • If any of the DLLs has an entry-point function (for initialization and termination code), the operating system calls the function. • One of the parameters passed to the entry-point function specifies a code that indicates the DLL is attaching to the process. • If the entry-point function does not return TRUE, the system terminates the process and reports the error. • Finally, the system modifies the executable code of the process to provide starting addresses for the DLL functions. Load-Time Function Interface in DLL • When the system starts a program, it uses the information the linker placed in the file to locate the names of DLLs – Search orders (typical) • The directory from which the application loaded • The system directory • The 16-bit system directory • The windows directory • The current directory • The directories that are listed in the PATH How to Link Implicitly • To implicitly link to a DLL, executables must obtain the following from the provider of the DLL: – A header file (.h file) containing the declarations of the exported functions and/or C++ classes. The classes, functions, and data should all have __declspec(dllimport) – An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.) – The actual DLL (.dll file). How to Link Implicitly • Executables using the DLL must include the header file containing the exported functions (or C++ classes) in each source file that contains calls to the exported functions. • From a coding perspective, the function calls to the exported functions are just like any other function call. • To build the calling executable file, you must link with the import library. If you are using an external makefile, specify the file name of the import library where you list other object (.obj) files or libraries that you are linking with. • The operating system must be able to locate the DLL file when it loads the calling executable. Recap • Use _declspec(dllexport) to declare a function to be exportable – _declspec(dllexport) DWORD MyFunction(…); • The build process will create .DLL and .LIB files – You should Link the .LIB file with the calling program – The .LIB file acts like a mini static library, that tells the linker to statically link the associated DLL file. – When using a DLL in a project, you can either provide the linker with the .LIB stub file, or some linkers allow you to specify the DLL directly (and the linker will then try to find the .LIB file, or may even attempt to create the .LIB file automatically). • Similar syntax to import a function – _declspec(dllimport) DWORD MyFunction(…); • If the calling (importing) client program is written in C++, necessary to specify the C calling convention – extern “C” _declspec(dllimport) DWORD … Run-time Linking (Explicit) • Requires the program to request specifically that a DLL be loaded or freed • Then, the program obtains the address of the required entry point and uses that address as the pointer in the function call • It is also known as Loading DLLs Dynamically Loading DLLs Dynamically • The real power behind DLL files is that they can be loaded into your program dynamically at execution time. • This means that while your program is running, it can search for and load in new components, without needing to be recompiled. • This is an essential mechanism for programs that allow plug-ins and extensions to be loaded at execution time. • To Dynamically load the DLL file, you can call the LoadLibrary function to get a handle to that library, and then pass that handle to one of several other functions to retrieve data from the DLL. LoadLibrary • A function used for mapping the specified executable module into the address space of the calling process • `The prototype for LoadLibrary is: HMODULE WINAPI LoadLibrary(LPCTSTR lpFileName); or HINSTANCE LoadLibrary(LPCTSTR lpLibFileName); • HMODULE (HINSTANCE) is a HANDLE to a program module. • lpFileName (lpLibFileName ) is the file name of the DLL you want to load. • Keep in mind that when loading a module, the system will check in your PATH first. – If you want the system to check in other specified directories first, use the SetDllDirectory function first. LoadLibrary • Once a DLL is loaded, and you have a handle to the module, you can do various things: – Use GetProcAddress to return a function pointer to a function in that library. – Use LoadResource to retrieve a resource from the DLL. – Once you are finished with a DLL file, and you want to remove it from memory, you can call the FreeLibrary function with the DLL's module handle. GetProcAddress • A function used for retrieving the address of an exported function or variable from the specified DLL • FARPROC GetProcAddress(HMODULE hModule, LPCTSTR lpProcNameName); Example: myPuts (Creating a .dll ) Example: Load-time Linking - Calling Program Example: Run-time Linking Homework • Writing a DLL • Writing programs to use your DLL – Using load time linking – Using run time linking