Original source: http://www.microsoft.com/china/community/program/originalarticles/techdoc/dll.mspx
table of Contents
Introduction DLL DLL Entry Function in MFC About Calling Conventions About DLL Definition File (.def) DLL Program and Calling Output Functions
introduction
The more large applications are composed of many modules, which complete relatively independent features, which work together to complete the work of the entire software system. There may be some modules that are more common and will be used when constructing other software systems. When building a software system, if you still compile all the source code of all modules to the entire application EXE file, some issues are generated: A disadvantage is to increase the size of the application, which will take up more disk space, program operation At the time, there will be a large memory space, causing waste of system resources; another disadvantage is that when writing large EXE programs, the compilation of all source code must be adjusted at each modification, and the complexity of the compilation process is added. It is also not conducive to the phase of the unit test. A completely different more efficient programming and operational environments on the Windows system platform, you can create a separate program module as a smaller DLL (Dynamic Linkable library) file and can be compiled and tested separately. At runtime, the system is loaded into memory space only when the exe program does call these DLL modules. This method not only reduces the size of the EXE file and the demand for memory space, but also allows these DLL modules to be used by multiple applications simultaneously. Windows yourself will implement some of the main system functions in the form of a DLL module. In general, the DLL is a disk file, with .dll, .drv, .fon, .sys, and many system files that are .EXE can be DLL. It consists of global data, service functions, and resources, which is partially loaded into the virtual space of the calling process at runtime, and becomes part of the calling process. If there is no conflict with other DLLs, the file is typically mapped to the same address of the process virtual space. A variety of export functions are included in the DLL module for serving the outside world. DLL can have its own data segment, but there is no own stack, use the same stack mode as the application called it; one DLL only has an instance in memory; DLL implements code encapsulation; DLL preparation and specific programming language And the compiler is independent. In the Win32 environment, each process copies its own read / write global variables. If you want to share memory with other processes, you must use a memory map file or declare a shared data segment. The stack memory required by the DLL module is allocated from the stack of the runtime process. Windows matches the process function call with the export function of the DLL file when loading the DLL module. The Windows operating system is only in the virtual address space of the DLL to map the DLL to the virtual address space that needs it. Any objects (including variables) created in the DLL function (including variables) are homed to use its threads or processes.
Call mode
1, static call mode: encoding the DLL uninstalled by the compilation system completes the DLL load and the end of the application (if other programs use this DLL, Windows reduces the DLL application records until all related programs end pair When the DLL is used, it releases it, simple and practical, but not flexible, can only meet the general requirements. Implicit calls: I need to use the LIB file that generates a dynamic connection library to the application, want to use the DLL When you function, you only have to explain. Implicit calls don't need to call LoadLibrary () and FreElibrary (). When the programmer is created a DLL file, the linker automatically generates a corresponding LIB import file. This file contains Each DLL export function symbol name and an optional identification number, but does not contain actual code. LIB files are compiled into the application project as a DLL replacement file. When the programmer compiles the application to generate an application by static link mode The call function in the application matches the export symbol in the lib file. These symbols or identification numbers entered into the generated EXE file. LIB file also contains the corresponding DL L file name (but not complete path name), The link is stored inside the exe file. When the DLL file is required during the application run, Windows discovers and loads the DLL according to this information, and then dynamic links to the DLL function via the symbolic name or identification number. All Applications The calling DLL file is loaded to the memory when the application EXE file is loaded. The executable program link is connected to a input library file (.lib file) containing the DLL output function information. The operating system loads when loading the executable program DLL. The executable passed the function name to call the DLL output function, the call method, and the internal other functions of the program. 2, dynamic call mode: Loading and uninstalling the DLL by the programmer to achieve the purpose of calling DLL It is more complicated in use, but more efficient use of memory is an important way to prepare a large application. Explicit calls: refers to the AFXLOADLIBRARY explicitly made by LoadLibrary or MFC in the application. Dynamic connection library is called, the file name of the dynamic connection library is the parameters of the above two functions, and use getProcAddress () to get the function you want to introduce. Sate, you can use the function as used as the user customized To call this introduction function. Before the application exits, you should use the AFXFREELIBRARY that FREELIBRARY or MFC to release the dynamic connection library. Straight Toned with Win32's LoadLibary function and specify the path to the DLL as a parameter. LoadLibary returns the Hinstance parameter, the application uses this parameter when calling the getProcAddress function. The GetProcAddress function converts the symbol name or identification number to the address within the DLL. The programmer can determine when the DLL file is loaded or not loaded, and the explicit link decides which DLL file is loaded at runtime. Using a DLL program must load (loadLibrary) to load the DLL to get the handle of a DLL module, then call the getProcAddress function to get the pointer to the output function, and you must uninstall the DLL (FREELIBRARY) before exiting. Windows will follow the search order below to locate the DLL:
Current Work Directory of Directory Process Contains EXE Files Windows System Directory Windows Directory lists a series of directories in the PATH environment variable
DLL in MFC
NON-MFC DLL: Refers to a class library structure that does not need to be MFC, and the DLL written directly with the C language is generally used by a standard C interface and can be called by an application written by non-MFC or MFC. Regular DLL: Like the Extension DLLs described below, it is written in the MFC class library. Obviously, there is a class inherited CWINAPP in the source file. It can also be subsequently connected to the MFC and dynamically connected to the MFC. The dynamic connection library of static connection to the MFC is only supported by the VC's professional and enterprise version. The output function in this class DLL application can be used by any Win32 program, including applications using MFC. The input function has the following form: Extern "C" export youRexPortedFunction (); if there is no externalN "C" modification, the output function can only be called from the C code. DLL applications derive from CWINAPP, but there is no message loop. Dynamic Link to the MFC Rule DLL Output Function The output function in the application can be used by any Win32 program, including the use of the MFC application. However, all functions output from the DLL should start with the following statement: AFX_Manage_State () This statement is used to switch the MFC module status correctly. The Regular DLL can be called by a application written by all languages that support DLL technology. In this dynamic connection library, it must have a class that inherited from cwinapp, and the DLLMAIN function is provided by the MFC without its explicit writing. Extension DLL: Used to achieve the reuse of classes inherited from the MFC, that is, with this type of dynamic connection library, can be used to output a class inherited from the MFC. Its output function can only be used with MFC and dynamically link to the MFC application. You can inherit your you want from the MFC, more suitable for your own class, and provide it to your app. You can also provide you with an object pointer for MFC or MFC inherited class. The Extension DLL is created using the MFC's dynamic connection versions, and it is only called by the application written by the MFC class library. Extension DLLS and Regular DLLs are different, it does not have objects of CWINAPP, so you have to add initialization code and end code for your own DLLMAIN function. Compared with the rule DLL, there is different: 1, it does not have objects derived from cwinapp; 2. It must have a DLLMAIN function; Returns 0; 4, if it wants to output a CRUNTIMECLASS type object or resource, you need to provide an initialization function to create a CDynlinkLibrary object. Also, it is necessary to output the initialization function; 5, the MFC application using the extended DLL must have a class derived from the CWINAPP, and generally call the extension DLL initialization function in InitInstance.
DLL entry function
1. Each DLL must have an entry point, and DLLMAIN is a default entry function. DllMain is responsible for initializing and ending, whenever a new process or the new thread of the process accesses the DLL, or if each process or thread accesses the DLL does not use the DLL or end, it will call DLLMAIN. However, using TerminateProcess or TerminateThread ending processes or threads without calling DLLMAIN. Dllmain's function prototype:
Bool apientry dllmain (Handle Hmodule, DWORD UL_REASON_FOR_CALL, LPVOID
LPRESERVED)
{
Switch (ul_reason_for_call)
{
Case DLL_Process_attach:
.......
Case DLL_THREAD_ATTACH:
.......
Case DLL_THREAD_DETACH:
.......
Case DLL_PROCESS_DETACH:
.......
Return True;
}
}
parameter:
HMOUDLE: It is a handle pointing to his hand when the dynamic library is called (actually, it is a selector that points to the _dgroup segment); ul_reason_for_call: is a sign of the cause of the dynamic library. When a process or thread is loaded or unloaded, the operating system calls the entry function and describes the reason why the dynamic connection library is called. All of it is: DLL_PROCESS_ATTACH: The process is called; DLL_THREAD_ATTACH: thread is called; DLL_PROCESS_DETACH: The process is stopped; DLL_THREAD_DETACH: The thread is stopped;
LPRESERVED: is a parameter reserved by the system;
2, _dllmaincrtstartup
In order to use the "C" CRT, C Run Time Library DLL version (multi-thread), a DLL application must specify _dllmainCrtStartup as an entry function, and the DLL initialization function must be DLLMAIN. _DllMainCrtStartup Complete the following tasks: When the process or thread bundle (Attach) is "C" CRuntime Data) allocates space and initialization, constructs the global "C " object when the process or thread is bundled, and constructs the global "C " object, when the process or thread is terminated using the DLL (Detach When Cruntime Data is cleaned up, the global "C " object is destroyed. It also calls the Dllmain and RawdllMain functions. RawdllMain is required when the DLL application is dynamically linked to the MFC DLL, but it is static link to the DLL application. The reason is explained when describing state management.
About the call agreement
There are two conventions for dynamic library output functions: call conventions and name modifications.
1) Calling Convention: Decide the order of the stack and out of the stack when the function parameter is transmitted, and the argument is bounced by the caller or the caller, and the compiler is used to identify the modification of the function name.
The function call is agreed to have a variety, here is simple to say:
1. __ stdcall calls agreement equivalent to the PASCAL call convention used in the 16-bit dynamic library. In the 32-bit VC 5.0, the PASCAL call convention is no longer supported (in fact it has been defined as __stdcall. In addition to __pascal, __ fortran and __syscall are not supported), replaced by __stdcall call agreement. The two are substantially consistent, that is, the function's parameters pass the right left through the stack through the stack, the called function is returned to the memory stack of the transfer parameters, but the different part of the function name (about the modified part of the function name) The detailed description will be described later. _Stdcall is the default call mode of the Pascal program. It is usually used in the Win32 API. The function uses the stack of right to left, and the stack is cleared when you exit. The VC compiles the function before adding a downline prefix in front of the function name, plus the number of bytes of "@" and parameters after the function name. 2, c call convention (ie, using __cdecl keyword description) Press the parameter from right to left, and populates the argument by the caller. For the memory stack of the transfer parameters, it is maintained by the caller (for this, the function that implements variable parameters can only use the call convention). In addition, there is also different in terms of function name modification. _CDECL is the default call mode of the C and C programs. Each function that calls it contains the code that clears the stack, so the resulting executable size is larger than the call _stdcall function. The function uses the stack of right to left. VC compiles the function and adds a downline prefix in front of the function name. It is an MFC default call agreement. 3, __ fastCall call agreement is "person", such as its name, its main feature is fast, because it passes the parameter through the register (actually, it uses ECX and EDX to transfer the first two double words (DWORD) or smaller The parameters, the remaining parameters are still transmitted to the left stack, the called function is returned to the internal memory stack of the transfer parameters before returning), and in terms of the function name modification, it is different from the top. _FastCall mode functions use register pass parameters, and VC compiles the function after the "@" prefix in front of the function name, add the number of bytes of "@" and parameters after the function name. 4. ThisCall is only applied to the "C " member function. The THIS pointer is stored in the CX register, the parameter is left from right to left. Thiscall is not a keyword, so it cannot be designated by the programmer. 5, Naked Call When using 1-4 call conventions, if necessary, the compiler generates code to save the ESI, EDI, EBX, EBP registers, generate code recovery of these registers when entering the function. Naked Call does not produce such a code. Naked Call is not a type modifier, so you must use the _declspec. Keywords __stdcall, __ cdecl, and __fastcall can be selected before the functionality of the function you want to output, or you can choose the SETTING ... / C / C / Code Generation item of the compilation environment. When the keyword before the output function is not in the compilation environment, the keyword before the output function is added directly before the output function is valid. The corresponding command line parameters are / Gz, / GD, and / GR, respectively. The default state is / gd, ie __cdecl. To fully imitate the Pascal call, you must first use the __stdcall call convention, as for the function name modification, can be imitated by other methods.
There is also a WINAPI macro, Windows.h supports this macro, which can translate the function into an appropriate call agreement, in Win32, it is defined as __stdcall. Use WinAPI macros to create your own APIS. 2) Name modification agreement
1. Decoration Name "C" or "C " function is identified by the modifier (compilation and link). The modisle name is a string generated when the compiler is generated when the compile function is defined or the prototype. Some cases are necessary to use the modifier of the function, such as the output "C " overload function, constructor, the structure, the destructor, and call "C" or "C " function in the assembly code. Whenever the modification of the function name, class name, call agreement, return type, parameter, etc.
2, the name modification will change with the adjustment agreement and the compilation species (C or C ). The function name modification is different from the compilation species and the call agreement, and below will be explained.
A, C compile time function name modification regulations: __stdcall call agreed to add a downline prefix before the output function name, and then add a "@" symbol and its parameters, format is _functionName @ number. __Cdecl call conventions only add a downline prefix before the output function name, format is _functionName. __Fastcall call agreed to add a "@" symbol before the output function name, the later is also a "@" symbol and its parameters, the format is @ functionName @ number. They do not change the case sensitive in the output function name, which is different from the PASCAL call, and the function name of the Pascal agreed output without any modification and all uppercase.
B, C compile function name modification agreement rules:
__stdcall call convention:
1, with the beginning of the "?" Identification function name, then follow the function name; 2. After the function name is labeled with the "@@ YG" identifies the beginning of the parameter table, follow the parameter table;
X - Void, D - Char, E - Unsigned Char, F - Short, H - INT, I - UNSIGNED INT, J - Long, K - Unsigned Long, M - Float, N- -Double, _n - bool, ....
PA - represents a pointer, the subsequent document indicates the pointer type, if the same type of pointer continuously appears, instead of "0", one "0" represents a repetition; 4, the first item of the parameter table is the return value of the function. Thereafter, the data type of the parameter is subsequently, the pointer identifies the end of its index; 5, after the parameter table identifies the end of the entire name, if the function does not parameters, the "z" identification ends. The format is "? Functionname @@ yg ***** @@ yg * xz", for example
Int test1 (char * var1, unsigned long) ----- "? test1 @@ yghpadk @ z"
Void test2 () ----- "? test2 @@ ygxxz" __ cdecl call agreement: Rule the above _stdcall call convention, just the start identification of the parameter table is "@@ ya" above the "@@ ya" .
__fastcall call convention: Rule the above _stdcall call convention, just the start identification of the parameter table changes from the "@@ yg" above "@@ yi". The province of VC to the function is "__CEDCL", which will only be called by C / C .
Function about DLL
There are two functions in the dynamic link library: export function and internal function (INTERNAL FUNCTION). The export function can be called by other modules, and the internal function is used inside the DLL program that defines their DLL programs.
The method of output functions has the following:
1, traditional method
Specify functions or variables to enter in the Export section of the module definition file. The syntax format is as follows:
EntryName [= INTERNAME] [@ORDINAL [NONAME]] [Data] [private]
among them:
EntryName is the name of the output function or the data referenced; INTERNALNAME is with ENTRYNAME; @ORDinal represents the sequence number (index) in the output table; Noname is used only when the sequence number is output (not using entryName); data represents the output It is a data item that the program that uses DLL output data must declare that the data item is _Declspec (dllimport).
In the above, only the entryName item is required, and others can be omitted.
For the "C" function, ENTRYNAME can be equivalent to the function name; however, for the "C " function (member function, non-member function), EntryName is a modifier. You can get a modulation name you want to output from the .map image file, or use dumpbin / symbol, then write them in the output module of the .def file. Dumpbin is a tool provided by VC.
If you want to output a "C " class, write the data and members of the data to the member to the .def module definition file.
2, output in the command line
Specify the / export command line parameters for the link program LINK, and output the relevant functions.
3. Use the modified symbols provided by the MFC_Declspec (DLLEXPORT)
In order to output the function, class, data declaration to output, plus the _Declspec (DLLEXPORT) modifier indicates the output. __DECLSPEC (DLLEXPORT) can remove the underscore prefix from the output function name in the case of C. EXTERN "C" makes it possible to use C compilation in C . Define the "C" function under C "requires to add externaln" c "keywords. Use extern "C" to indicate that the function uses C compile. The output "C" function can be called from the "C" code.
For example, in a C file, there is a function:
Extern "C" {void __declspec (dllexport) __cdecl test (int var);}
Its output function name is: TestMFC provides some macros, there is such a role.
AFX_CLASS_IMPORT: __ DECLSPEC (DLLEXPORT)
AFX_API_IMPORT: __ DECLSPEC (DLLEXPORT)
AFX_DATA_IMPORT: __ DECLSPEC (DLLEXPORT)
AFX_CLASS_EXPORT: __ DECLSPEC (DLLEXPORT)
AFX_API_EXPORT: __ DECLSPEC (DLLEXPORT)
AFX_DATA_EXPORT: __ DECLSPEC (DLLEXPORT)
AFX_EXT_CLASS: #ifdef _afxext
AFX_CLASS_EXPORT
#ELSE
AFX_CLASS_IMPORT
AFX_EXT_API: #ifdef _afxext
AFX_API_EXPORT
#ELSE
AFX_API_IMPORT
AFX_EXT_DATA: #IFDef_afxext
AFX_DATA_EXPORT
#ELSE
AFX_DATA_IMPORT
Macro like AFX_EXT_CLASS, if used in the implementation of the DLL application, indicates the output (because _afx_ext is defined, it is usually specified in the identity parameter of the compiler to specify this option / D_AFX_ext); if used to use the DLL application In, the input is indicated (_AFX_ext is not defined). To output the entire class, use _DECLSPEC (_dllexpot) to class; use the member function to output the class, using _declspec (_dllexport). Such as:
Class AFX_EXT_CLASS CTEXTDOC: PUBLIC CDOCUMENT
{
...
}
EXTERN "C" AFX_EXT_API VOID WINAPI INITMYDLL ();
In these methods, it is best to use the third, convenient to use; second is the first, if the sequence number is output, the call efficiency will be higher; the most second.
Module definition file (.def)
Module definition file (.def) is a text file for one or more module statements used to describe the DLL property, each DEF file must contain at least the following module definition statement:
The first statement must be a library statement, pointing out the name of the DLL;
The exports statement lists the name of the exported function; the function to the output to be output is listed under Exports. This name must be exactly the same as the name of the definition function, so get a function name without any modified.
You can use the Description statement to describe the use of DLL (optional);
";" Commented on a row (optional).
The relationship between the DLL program and the program that calls its output function
1, DLL and processes, relationships between threads
The DLL module is mapped to the virtual address space that calls its process.
The memory used by the DLL is allocated from the virtual address space of the calling process, and can only be accessed by the thread of the process.
The handle of the DLL can be used to use; the handle of the calling process can be used by the DLL.
DLL uses the stack of the calling process.
2. About shared data segment