Relatively large application consists of many modules, these modules were completed relatively independent functions, they collaborate with each other to complete the work of the entire software . Which there may be some module features more common, will still be used to construct other software . Constructed software , the source code for all modules statically compiled into the entire application EXE , it will create some problems: a drawback is to increase the size of the application , it will take up more disk space, the run will also consume a large amount of memory space, resulting in a waste of resources; Another disadvantage is that in the preparation of large EXE , modify the reconstruction must be adjusted to compile all the source code, increasing the complexity of the compilation process is not conducive to unit testing stage.
Windows platform provides a completely different and more effective programming and runtime environment, you can create separate modules into smaller DLL (Dynamic Linkable Library) and can compile and test them separately. At runtime, the only case when the EXE you sure you want to call these DLL module, the will be loaded into the memory space. This approach not only reduces the size of the EXE and memory space requirements, and to make these DLL module can be used simultaneously by multiple application . Microsoft Windows will be some of the main functions in the form of a DLL module.For example, some of the basic functions of the IE is implemented by the DLL , it can be other applications calls and integration.
Generally speaking, the DLL is a disk (usually with a DLL extension), which consists of global data, functions and resources at run time the is loaded into the virtual space of the process, part of the calling process. There is no conflict with other DLL, the usually mapped to the same address of the process virtual space. Contains a variety of exported functions in the DLL module for providing services to the outside world. Windows DLL module is loaded process function calls the exported functions of the DLL to match.
In the Win32 environment, each process are copied to the read / write global variables. If you want to be shared with other processes memory, you must use memory-mapped or declare a shared data segment. DLL module stack memory is allocated from the stack of the running process.
The DLL now more easy to write. Win32 has been greatly simplifies the programming model, and from AppWizard and MFC class library support.
First, the export and import functions match
DLL contains an export function table. These export functions are linked by their symbolic names and identification number called integer with the outside world. Function table also contains the address of the function in the DLL. When the application loaded DLL module from time to time, it does not know the actual address of the calling function, but it knows the sign of the function name and identification number. Dynamic linking process dynamically loaded DLL module create a function call with the address of the function corresponding table. If you recompile and rebuild the DLL do not need to modify the , unless you change the symbolic name of the exported functions and parameters sequence.
The simple DLL only exported functions for the application , the more complicated DLL in addition to providing the exported functions also call other functions in the DLL . In this way, a special DLL that can both import function, but also import function. This is not a problem because of the dynamic linking process can handle the cross-correlations.
Exported functions in the DLL code must be like this clear statement:
__ declspec (dllexport) int MyFunction (int n);
But can also be listed in the module definition (DEF) export function, but doing so often leads to more trouble. In the application , the requirements of the corresponding input function like the following clear statement:
MyFuncition __ declspec (dllimport) int (int n);
Only import and export declaration does not make the application within the function call link to the corresponding DLL . of the project must specify the required input for the linker library (LIB ). And the application must contain at least one fact DLL function call.
, To establish a link with the DLL module
Application into the function and the exported functions in the DLL linked in two ways: implicit links and explicit links. The so-called implicit link do not need to specify the actual storage path of the DLL in the application , members do not need to care about the actual loading of DLL . Explicit link to the contrary.
Implicit link, staff in creating a DLL , the will automatically generate a corresponding LIB import . This contains symbolic names and optional identification number of each DLL exported functions, but does not contain the actual code. LIB as an alternative of the DLL is compiled into the project. When members compiler generated when the application is statically linked , the application call the function with the LIB export symbols to match these symbols or identification number into the generated EXE . LIB also contains the corresponding DLL name (but not the full path name), a link will store it internally in the EXE . Need to load the DLL when the running , Windows based on this information to find and load the DLL, and then through the symbolic name or identification number to achieve the dynamic link to the DLL function.
Explicit link mode, more suitable for the integrated development language (such as ). With explicit linking, members do not have to use the import , and but directly to call Win32 LoadLibary function, and as a parameter to specify the path to the DLL. LoadLibary returns the HINSTANCE parameter, the application use this parameter when calling the GetProcAddress function. The GetProcAddress function converts the symbolic name or identification number for the address inside the DLL.Suppose an export function of the DLL :
extern "C" __ declspec (dllexport) double SquareRoot (double d);
Here is an example of the application explicitly link the exported functions:
typedef double (SQRTPROC) (double);
SQRTPROC * pFunction;
VERIFY (hInstance = :: LoadLibrary ("c :/ / winnt / / system32 / / mydll.dll"));
VERIFY (pFunction = (SQRTPROC *) :: GetProcAddress (hInstance, "SquareRoot"));
double d = (* pFunction) (81.0) ;/ / call the DLL function
Implicit link, the application calls the DLL will be loaded in the application EXE loaded into memory; But if explicit link, members can decide when a DLL is loaded or not loaded . Explicit link to determine which DLL loaded at runtime . For example, a string resource DLL module loaded in English and the other in Spanish loaded. Application when the user selects the appropriate language and then load the corresponding DLL .
Third, the use of symbolic names link with the identification number of links
Link efficiency is low, the symbol name in the Win16 environment, all links when the identification number is the main link.Win32 environment, improve the efficiency of the symbolic name link. Microsoft now recommend the use of symbolic names link. DLL version of MFC library still use the identification number link. A typical MFC may be linked to hundreds MFC DLL function. EXE application identification number links body is relatively small, because it does not contain a long string of symbolic names of the import function .
Fourth, write a DllMain function
The DllMain function are the default entry point in the DLL module. This function is called when Windows loads DLL module.first calls the constructor of the global object, and then call the global function DllMain. The DllMain function not only in the link DLL is loaded into the process is called, (and other times) is called when the DLL module and the process of separation. Here is an example of of a framework DLLMain function.
extern "C" int APIENTRY DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved)
the if (dwReason == DLL_PROCESS_ATTACH)
TRACE0 ("EX22A.DLL Initializing! / N");
/ / Initialize
else if (dwReason = DLL_PROCESS_DETACH)
TRACE0 ("EX22A.DLL Terminating! / N");
/ / Clear
return 1 ;/ / success
who is not prepared for the DLL module a DLLMain function, the will be introduced from other runtime a default DllMain function version without any operation. Initiated and terminated in a single thread, the DllMain function is called. As by the dwReason parameter, as indicated.
Fifth, the module handle
The process DLL module HINSTANCE handle identifies globally unique 32-byte. Process there is a HINSTANCE handle. All of these modules handle is valid only within the specific process, they represent the starting address of the DLL or EXE module in the process virtual space. In Win32, the the HINSTANCE and HMODULE value is the same, the two types can be used interchangeably. Process module handle almost always equal to 0x400000 default handle to the DLL module load address is 0x10000000. If the same time a few DLL modules, each will have a different HINSTANCE value. This is because specify a different base address of the DLL created or relocation because the loader DLL code.
The module handle load resources is particularly important. The Win32 the FindResource function of with a HINSTANCE parameters. EXE and DLL has its own resources. If the application from the DLL resources, this parameter specifies the DLL module handle. If you need the resources that are contained in the EXE , specify the the EXE module handle.
But there is a problem before using these handles, how do you get them? If you need to get the the EXE module handle, call the Win32 function GetModuleHandle with a null parameter; DLL module handle, call the Win32 function GetModuleHandle DLL named parameters if necessary .
, Application How to find the DLL
If the application using LoadLibrary explicitly link in the parameters of this function, then you can specify the full path of the DLL . If you do not specify a path, or implicitly linked, Windows will follow the search order to locate the DLL:
1. The directory that contains the EXE ,
2. The current working directory of the process,
3. Windows directory,
4. Windows directory,
5. A series of directories listed in the Path environment variable.
There is a very prone to error trap. If you are using + + project development, and created a project specifically for the DLL module, and then copy the generated DLL to the directory, call the DLL module from the application . So far, everything is normal. Next made ??some changes to the DLL module regenerate new DLL , but you forget to copy the new DLL to the directory. The next time you run the when it is still loading the old version of the DLL , which have to be careful!
Microsoft + + is an effective tool for development and testing DLL, the can simply run from the DLL project . When you first such operation, commissioning will ask you for the path of the EXE . Each subsequent run DLL debugging , the debugger will automatically load the EXE . Then the EXE found using the above search sequence DLL , which means you have to set the PATH environment variable to let the disk that contains the DLL path, or you can copy the DLL to the directory path in the search sequence.