Dynamic link library (DLL) programming principle in Win32 Environment

Source: Internet
Author: User
Code
Large applications Program These modules are composed of many modules that complete relatively independent functions and work together to complete the work of the entire software system. Some modules may have common functions and will still be used when constructing other software systems. When constructing a software system Source code If all files are statically compiled into the entire application EXE file, some problems will occur: one drawback is that the application size is increased, which will occupy more disk space, when the program runs, it also consumes a large amount of memory space, resulting in a waste of system resources. Another drawback is that when writing a large exe program, you must adjust all the source code during each modification and reconstruction. Code It increases the complexity of the compilation process and is not conducive to the staged unit testing.

Windows provides a completely different and effective programming and running environment. You can create an independent program module as a smaller DLL (Dynamic linkable Library) file, they can be compiled and tested separately. During runtime, the system will load the EXE program to the memory space only when it does need to call these DLL modules. This method not only reduces the size of the EXE file and the need for memory space, but also enables these DLL modules to be used by multiple applications at the same time. Microsoft Windows itself implements some major system functions in the form of DLL modules. For example, some basic functions of IE are implemented by DLL files, which can be called and integrated by other applications.

Generally, a DLL is a disk file with a dll extension. It consists of global data, service functions, and resources and is loaded into the virtual space of the process by the system at runtime, become part of the calling process. If there is no conflict with other DLL, the file is usually mapped to the same address of the virtual space of the process. The DLL module contains various export functions to provide external services. When Windows loads the DLL module, it matches the process function call with the export function of the DLL file.

In the Win32 environment, each process copies its own read/write global variables. To share memory with other processes, you must use a memory ing file or declare a shared data segment. The stack memory required by the DLL module is allocated from the stack of the running process.

DLL is more and more easy to write. Win32 has greatly simplified its programming mode and has many support from Appwizard and MFC class libraries.

1. Matching of Export and Import Functions

The DLL file contains an export function table. These export functions are associated with the external world by their symbolic names and integers called identifiers. The function table also contains the address of the function in the DLL. When an application loads the DLL module, it does not know the actual address of the called function, but it knows the symbol name and ID number of the function. When the DLL module is loaded during the dynamic link process, a table corresponding to the function call and function address is dynamically created. If you re-compile and recreate the DLL file, you do not need to modify the application unless you change the symbolic name and parameter sequence of the export function.

Simple DLL files only provide export functions for applications. In addition to providing export functions, complicated DLL files also call functions in other DLL files. In this way, a special dll can have both the import function and the import function. This is not a problem because the dynamic link process can handle cross-related situations.

In the DLL code, the export function must be explicitly declared as follows:

_ Declspec (dllexport) int myfunction (int n );

However, you can also list the export functions in the module definition (DEF) file, but this will often cause more trouble. In terms of applications, it is required to explicitly declare the corresponding input functions as follows:

_ Declspec (dllimport) int myfuncition (int n );

Only the import and export declarations do not allow function calls within the application to be linked to the corresponding DLL file. The project of the application must specify the required input Library (LIB file) for the linked program ). In addition, the application must contain at least one call to the DLL function.

2. establish a link with the DLL module

The application import function can be linked to the export function in the DLL file in two ways: implicit link and explicit link. The so-called implicit link means that the actual storage path of the DLL file does not need to be specified in the application, and the programmer does not need to care about the actual loading of the DLL file. The explicit link is the opposite.

The implicit link method is used. When a programmer creates a DLL file, the link program automatically generates a corresponding lib import file. This file contains the symbolic name and optional Identification Number of each DLL export function, but does not contain the actual code. The LIB file is compiled into the application project as an alternative DLL file. When programmers compile and generate an application through static links, the calling functions in the application match the exported symbols in the Lib file. These symbols or identifiers enter the generated EXE file. The LIB file also contains the corresponding DLL file name (but not the full path name), and the link program stores it in the EXE file. When a DLL file needs to be loaded while the application is running, Windows will find and load the DLL based on the information, and then use the symbolic name or identification number to achieve dynamic links to the DLL function.

Explicit links are suitable for integrated development languages (such as VB. With the explicit link, the programmer does not need to use the import file, but directly calls the Win32 loadlibary function and specifies the dll path as the parameter. Loadlibary returns the hinstance parameter, which is used by the application to call the getprocaddress function. The getprocaddress function converts the symbolic name or identification number to the internal address of the DLL. Assume there is a DLL file for exporting the following functions:

Extern "C" _ declspec (dllexport) Double squareroot (double D );

The following is an example of an explicit link from the application to the export function:

Typedef double (sqrtproc) (double );
Hinstance;
Sqrtproc * pfunction;
Verify (hinstance =: loadlibrary ("C: \ winnt \ system32 \ mydll. dll "));
Verify (pfunction = (sqrtproc *): getprocaddress (hinstance, "squareroot "));
Double D = (* pfunction) (81.0); // call this DLL Function

In the implicit link mode, all DLL files called by the application will be loaded into the memory when the application EXE file is loaded. However, if the explicit link mode is used, programmers can decide when to load or not load DLL files. The explicit link determines the DLL file to be loaded at runtime. For example, a DLL module with string resources can be loaded in English, while another can be loaded in Spanish. The application loads the corresponding DLL file after selecting the appropriate language.

3. Use the symbolic name link and the identification number Link

In the Win16 environment, the symbolic name link efficiency is low, and the identification number link is the main link method at that time. In the Win32 environment, the efficiency of symbolic link is improved. Microsoft currently recommends the use of symbolic links. However, the dll version in the MFC library still uses the identification number link. A typical MFC program may be linked to hundreds of mfc dll functions. The EXE file of the application that uses the identification code link is relatively small, because it does not need to contain the long string symbol name of the import function.

4. Write the dllmain Function

The dllmain function is the default entry point of the DLL module. This function is called when Windows loads the DLL module. The system first calls the constructor of the global object and then calls the global function dllmain. The dllmain function is called not only when the DLL link is loaded to the process, but also when the DLL module is separated from the process (and other times. The following is an example of the Framework dllmain function.

Hinstance g_hinstance;
Extern "C" int apientry dllmain (hinstance, DWORD dwreason, lpvoid lpreserved)
{
If (dwreason = dll_process_attach)
{
Trace0 ("ex22a. dll initializing! \ N ");
// Perform initialization here
}
Else if (dwreason = dll_process_detach)
{
Trace0 ("ex22a. dll terminating! \ N ");
// Clear the job here
}
Return 1; // success
}

If the programmer has not compiled a dllmain function for the DLL module, the system will introduce a default dllmain function version from other runtime libraries without any operation. The dllmain function is also called when a single thread is started and terminated. As indicated by the dwreason parameter.

5. module handle

Each DLL module in a process is identified by a globally unique 32-byte hinstance handle. The process itself has an hinstance handle. All these module handles are valid only within a specific process. They represent the starting address of the DLL or EXE module in the process virtual space. In Win32, the values of hinstance and hmodule are the same. You can replace these two types. The process module handle is almost always equal to 0x400000, while the default DLL module load address handle is 0x10000000. If the program uses several DLL modules at the same time, each has a different hinstance value. This is because different base addresses are specified when the DLL file is created, or the DLL code is relocated by the loader.
The module handle is particularly important for loading resources. The findresource function of Win32 contains an hinstance parameter. Both EXE and DLL have their own resources. If the application needs resources from the DLL, specify this parameter as the module handle of the DLL. If you need resources in the EXE file, specify the module handle of the exe.

But before using these handles, how do you get them? To obtain the EXE module handle, call the Win32 function getmodulehandle with the null parameter. If the DLL module handle is required, call the Win32 function getmodulehandle with the DLL file name as the parameter.

6. How does the application find the DLL file?

If the application uses the loadlibrary explicit link, you can specify the complete path of the DLL file in this function parameter. If you do not specify a path or perform an implicit link, Windows will follow the search order below to locate the DLL:

1. directory containing the EXE file,
2. current working directory of the process,
3. Windows System directory,
4. Windows Directory,
5. A series of directories listed in the PATH environment variable.

There is a trap that is prone to errors. If you use VC ++ for project development and create a project for the DLL module, copy the generated DLL file to the system directory, and call the DLL module from the application. So far, everything is normal. After some modifications are made to the DLL module, a new DLL file is generated again, but you forgot to copy the new DLL file to the system directory. The next time you run the application, it still loads the DLL file of the old version. Be careful!

7. debug the DLL Program

Microsoft Vc ++ is an effective tool for developing and testing DLL. You only need to run the debugging program from the DLL project. When you perform this operation for the first time, the debug program will ask you about the path of the EXE file. After that, each time a DLL is run in the debugging program, the debugging program automatically loads the EXE file. Then the EXE file uses the above search sequence to find the DLL file, which means you must set the PATH environment variable to make it include the disk path of the DLL file, alternatively, you can copy the DLL file to the directory path in the search sequence.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.