introduction
The more large applications consist of many modules, which complete relatively independent features, each other, each other
Collaborate to complete the work of the entire software system. There may be some modules that are more common, and the system is constructed.
Turnover will still be used. When constructing a software system, if the source code of all modules is static to the entire application
In the order EXE file, some issues will be generated: a disadvantage is to increase the size of the application, which will take up more magnetic
The disc space, the program is running, and there will be large memory space, causing waste of system resources; another disadvantage is
When writing a large EXE program, you must adjust all source code every time you modify it, add the compilation process.
Complexity, not conducive to the phase of the unit test.
A completely different more effective programming and operating environment on the Windows system platform, you can independently
The program module is created as a smaller DLL (Dynamic Linkable library) file and can compile them separately
And test. At runtime, the system will only use it when the exe program is to call these DLL modules.
They are loaded into memory space. This method not only reduces the size of the EXE file and the demand for memory space, but also
These DLL modules can be used by multiple applications simultaneously. Windows yourself will have some main system features
DLL module is implemented in the form of a DLL module.
In general, the DLL is a disk file with .dll, .drv, .fon, .sys and many .EXE is extension
The named system file can be a DLL. It consists of global data, service functions, and resources, is loaded by the system at runtime.
In the virtual space of the calling process, becomes part of the calling process. If there is no conflict with other DLLs,
Documents are typically mapped to the same address of the process virtual space. The DLL module contains various export functions for the outside world.
Provide services. DLL can have its own data segment, but there is no own stack, use the same as the application called it.
Stack mode; one DLL only has an instance in memory; DLL implements code encapsulation; DLL preparation
The programming language and compiler have nothing to do.
In the Win32 environment, each process copies its own read / write global variables. If you want to share with other processes
Enjoy memory, you must use a memory map file or declare a shared data segment. The stack memory required by the DLL module is
Assigned from the stack of the running process. Windows calls the process function with DLL text when loading a DLL module
The export function of the part matches. The Windows operating system is just the operation of the DLL to map the DLL to the needs of it.
Cheng's virtual address space is going. Any object (including variables) created by the code in the DLL function is hit by it.
Threads or processes all.
Call mode
1, static call mode: DLL uninstalled encoded by the compilation system completes the DLL load and the application ends of the application (eg
There are other programs that use this DLL, and Windows reduces the DLL application record until all related programs end
Release it when the DLL is used, simple and practical, but not flexible enough to meet the general requirements.
Implicit call: You need to add the .lib file that generated when a dynamic connection library is generated is added to the application.
When you want to use the function in the DLL, you only have to explain it. Implicit call does not need to call LoadLibrary () and FREEL
Ibrary (). When a programmer is created a DLL file, the link will automatically generate a corresponding LIB guide.
Into the file. This file contains the symbol name and optional identification number of each DLL export function, but does not contain actual
Code. The lib file is compiled into the application project as an alternate file for the DLL.
When the programmer recompores an application by static link mode, the call function in the application matches the export sign in the lib file, these symbols or identification numbers enter the generated EXE file. The LIB file also contains
The DL L file name (but not a complete path name), the linker stores it inside the EXE file.
When the DLL file is required during the application run, Windows discovers and loads DL according to this information.
L, then dynamic links to the DLL function via the symbol name or identification number. All DLL texts called by the app
Both will be loaded into memory when the application exe file is loaded. The executable chain is connected to a containing DLL
Output function information Enter library file (.lib file). The operating system loads the DLL when loading the executable program. can
The execution program calls the DLL output function directly through the function name, the call method, and the internal it is the same.
of.
2, dynamic call mode: is the purpose of loading and uninstalling the DLL by the programmer to achieve the purpose of calling the DLL,
It is more complicated to use memory more effectively, which is an important way to prepare large applications.
Explicit call: refers to the AFXLOADLIBRARY provided by LoadLibrary or MFC in the application
The form of the dynamic connection library that you do, the file name of the dynamic connection library is the parameter of the two functions above, and then
Get the function you want to introduce with getProcAddress (). Since then, you can use this application to be customized.
The function of the righteous function calls this introduction function. FREELIBRARY or MFC should be used before the application exits
AFXFREELIBRARY is provided to release dynamic connection libraries. Call directly of Win32 LoadLibary function and specify
The path of the DLL is used as a parameter. LoadLibary returns a Hinstance parameter, the application is calling getProcAdd
This parameter is used when the RESS function is used. The getProcAddress function converts the symbol name or identification number to the DLL inside.
site. The programmer can determine when the DLL file is loaded or not loaded, the explicit link decides which DLL is loaded at runtime
file. Using a DLL program must load (loadLibrary) to load the DLL to get a DLL model
The handle of the block, then call the GetProcAddress function to get the pointer to the output function, you must uninstall DL before exiting
L (freeElibrary).
Windows will follow the search order below to locate the DLL:
Contents containing the exe file
Current work catalog of the process
Windows system catalog
Windows catalog
A series of directories listed in the PATH environment variable
DLL in MFC
Non-MFC DLL: Refers to the class library structure that does not have to be written directly with the C language written, and its output is generally
It is 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. Obvious character is
There is a class inherited CWINAPP in the source file. It can also be finely connected to the MFC and dynamically connected to the MFC.
of.
The dynamic connection library of static connection to the MFC is only supported by the VC's professional and enterprise version. This class DLL application
The output function of the sequence can be used by any Win32 program, including the use of the MFC application. Input function has
The following form:
Extern "C" export youRexportedFunction ();
If there is no extern "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 in the application can be used by any Win32 program
, Including applications using MFC. However, all functions output from the DLL should start with the following statement:
AFX_MANAGE_STATE (AFXGETSTATICModuleState ())
This statement is used to correctly switch the MFC module status.
The Regular DLL can be called by a application written by all languages that support DLL technology. In this dynamic
In the connection library, it must have a class that inherited from cwinapp, and the DLLMAIN function is provided by the MFC, no
I have explicitly written it.
EXTENSION DLL: Used to achieve the reuse of classes from the MFC, that is, this type of
Dynamic connection library can be used to output a class that is inherited from the MFC. Its output function can only be used by MF
C and dynamically link to the MFC application. You can inherit your you want from MFC, it is more suitable for yourself.
Class and provide it to your app. You can also provide you with MFC or MFC inheritance class freely.
Object pointer. Extension DLL is created using the dynamic connection version of the MFC, and it is only used by MFC class libraries
The written application is called. Extension DLLS and Regular DLLs are different from CWINAP
P Inherited the object, so you have to add initialization code and end code for your own DLLMAIN function.
Compared with the rule DLL, there is a difference:
1. It does not have objects derived from cwinapp;
2, it must have a DLLMAIN function;
3, DLLMAIN calls the AFXINITEXTENSIONMODULE function, you must check the return value of the function, if you return 0
DLLMMAIN also returns 0;
4. If it wants to output a CRUNTIMECLASS type object or resource, you need to provide an initialization function.
Create a cdynlinklibrary object. And, it is necessary to output the initialization function;
5. The MFC application that uses the extended DLL must have a class derived from cwinapp, and generally in init.
The initialization function of the extended DLL is called in the installation of instance.
DLL entry function
1. Each DLL must have an entry point, and DLLMAIN is a default entry function. DllMain is responsible for the initial
End work, whenever a new process or new thread of the process accesses the DLL
DLLMAIN will be called for each process or thread no longer uses DLL or end. However, use Terminat
Eprocess 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 that is passed when the dynamic library is called (actually, it is a selector pointing to the _dgroup segment);
UL_REASON_FOR_CALL: is a logo that describes the cause of the dynamic library. When a process or thread is loaded or unloaded
When the library is connected, the operating system calls the entry function and describes the reasons why the dynamic connection library is called. It's all possible
The value 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), one
DLL application must specify _dllmainCrtStartup as an entry function, the DLL initialization function must be a DLL
Main.
_DllMainCrtStartup complete the following tasks: "C" when the process or thread is bundled (Attach) to the DLL
Cruntime Data Assign space and initialization and construct global "C " objects, when the process or
When thread terminates the DLL (Detach), clean the C Runtime Data and destroy the global "C " object. It still
Call the Dllmain and RawdllMain functions.
RawdllMain is required when the DLL application dynamically links to the MFC DLL, but it is static link to DL
L 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 caller is also
Is the caller popped the argument, 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 32-bit VC
5.0 Pascal call conventions no longer supported (actually it has been defined as __stdcall. Except for __pascal
__ fortran and __syscall are not supported), replaced by __stdcall call conventions. Both essentially
Up to consistent, the function's parameters pass the right to the left through the stack pass, the function being called in the returning to the transfer parameters
Memory stack, but different is the modified portion of the function name (the modified portion of the function name will be described in detail later).
_stdcall is the default call mode of the Pascal program, usually used in the Win32 API, the function is used from the right
To the left stack, you will clear the stack when you exit. VC will compile the function before the function name is before
Puzzle, add "@" and parameters after the function name.
2, C call convention (ie, using __cdecl keyword description) Press from right to left sequential parameters to enter the stack, by the caller
Summary outlet. For the memory stack of the transfer parameters, it is maintained by the caller (for this, the letter to realize variable parameters)
The number can only be used to use the call.). 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. Function adopts the stack from right to left
the way. 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", the main feature is fast, because it is through the register
Transfer parameters (actually, it transmits the first two double words (DWORD) or smaller parameters with ECX and EDX, the rest
The parameter is still in the right left stack, the called function is returned to the memory stack of the transfer parameter, in the function name
The decoration agreement is different from the top two.
_fastCall mode functions use registers to pass parameters, VC will compile functions after the function name, "@
"Prefix, add" @ "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 parameters are from right to left
Pressure. Thiscall is not a keyword, so it cannot be designated by the programmer.
5, Naked Call When using 1-4 call, if necessary, the compiler will generate code when entering the function.
To save ESI, EDI, EBX, EBP registers, generate code recovery these registers when exiting functions.
Naked Call does not produce such a code. Naked Call is not a type modifier, so it must be combined with _declspec
use.
Keywords __stdcall, __ cdecl, and __fastcall can be added directly before the function to be output,
Setting ... / c / c / code generation item selection in compiler. When adding keywords before the output function
The choice of compilation environments is not valid before the keyword before the output function is added. Their corresponding command line parameters
It is / Gz, / GD, and / GR, respectively. The default state is / gd, ie __cdecl.
To completely imitate the Pascal call agreement First, you must use the __stdcall call convention, as for the function name.
Set, you can imitate other methods. There is also a worth mentioning that WinApi macro, Windows.h supports the macro.
It can translate the function into an appropriate call agreement, in Win32, it is defined as __stdcall. Use Wi
NAPI macros can create our own APIS.
2) Name modification agreement
1, Decoration Name
"C" or "C " function is identified by a modified name inside (compiled and link). The modifier is the compiler in compilation
Function definitions or strings generated when the prototype. Some cases are necessary to use the modification of the function, such as in the module
文件 文件 头 指 输 文件 函 重 或 或 或 或 或 如 或 或 或 或 或 或 或 或 或 或 或 或 或 或 或 或 或 或 或
"C " function, etc.
The modified 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 ). Function name modification agreement with compilation
The class and call agreement are different, and the following will be described below.
A, C compile time function name modification agreement rules:
__stdcall call agreement plus a downline prefix before the output function name, and then add a "@" symbol and its
The number of 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, and then a "@" symbol and its ginseng
Number of bytes, 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 Pascal is appointed.
The function name has no modification and all uppercase.
B, C compile function name modification agreement rules:
__stdcall call convention:
1. Taking the beginning of the "?" Identification function name, then follow the function name;
2, the function name is behind the "@@ YG" identifies the beginning of the parameter table, and then following the parameter table;
3, the parameter table is indicated by code:
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 code indicates the pointer type, if the same type of pointer appears continuously, "0" generation
For, a "0" represents a repetition;
4. The first item of the parameter table is the type of return value of the function, and then the data type of the parameter is followed, and the pointer identifies it in its
Index data type;
5. After the parameter table identifies the end of the entire name, if the function is not parameters, the "z" identifier ends.
The format is "? Functionname @@ yg ***** @ z" or "functionname @@ yg * xz",
E.g
Int test1 (char * var1, unsigned long) ----- "? test1 @@ yghpadk @ z"
Void Test2 () ----- "? test2 @@ ygxxz"
__cdecl call convention:
The rule is the same above _stdcall call, but the start identification of the parameter table is changed from "@@ YG" to "@@ ya".
.
__fastcall call convention:
The rule is the same above _stdcall call, but the beginning identification of the parameter table is changed from the above "@@ yg" to "@@ yi"
.
The province of VC to the function is "__CEDCL", which will only be called by C / C .
Function about DLL
Dynamic Link Library Defines Two Functions: Export Function and Internal Functions (INTERNAL F
Unction. 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 [= INTERNALNAME] [@ORDINAL [NONAME]] [DATA] [private] where:
EntryName is the name of the output function or data being referenced;
INTERNAME with ENTRYNAME;
@ORDINAL indicates the sequence number (index) in the output table;
Noname is used only when outputting sequence number (no entryname);
DATA indicates that the output is the data item, the program that uses the DLL output data must declare the data item as _Declspec (D
LLIMPORT.
In the above, only the entryName item is required, and others can be omitted.
For "C" functions, EnTryName can be equivalent to the function name; but for the "C " function (member function,
Non-member functions, entryName is a modifier. Can be obtained from the .MAP image file to get the function of the output function
Ornament, or use dumpbin / symbols to get it, then write them in the output module of the .def file. DUMPB
IN is a tool provided by VC.
If you want to output a "C " class, write the data and members of the data to be output 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) In C call conventions, the underscore prefix of the output function name can be removed in C compile
. EXTERN "C" makes it possible to use C compilation in C . Define "C" function in "C " needs to be added
EXTERN "C" keywords. Use extern "C" to indicate that the function uses C compile. The output "C" function can be
Call from "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: Test
MFC 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 for DLL applications, indicates output (because
_Afx_ext is defined, usually specified in the identification parameter of the compiler); if used for use
In the DLL application, the input is indicated (_AFX_ext is not defined).
To output the entire class, use _declspec (_dllexpot) for class; to output a member function of the class,
Number use _declspec (_dllexport). Such as:
Class AFX_EXT_CLASS CTEXTDOC: PUBLIC CDOCUMENT
{
...
}
EXTERN "C" AFX_EXT_API VOID WINAPI INITMYDLL ();
Among these methods, it is best to use the third, convenient to use; second is the first, if the sequence number is output, adjust
The use efficiency will be higher; the other is the second.
Module definition file (.def)
Module definition file (.def) is a text file composed of one or more module statements used to describe the DLL attribute, each
A 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
The name must be exactly the same as the name of the definition function, so get a function name without any modification.
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
The global variable defined by the DLL can be called process access; the DLL can access global data of the calling process. Use
Every process of a DLL has its own DLL global variable instance. If multiple threads are sent to access the same variable, they need
To use a synchronization mechanism; for a variable of a DLL, if you want each thread that uses the DLL, you should
Use thread local storage (TLS, Thread Local Strorage).
Add a precompiled instruction in the program, or the setting data segment attribute can also be reached in the project settings of the development environment.
Objective. These variables must be assigned to these variables. Otherwise, the compiler will put the variables that are not assigned to the initial value in a name that is not initialized.
Data segment.