1. dll Concept
DLL (Dynamic linkable Library), which can provide some functions, variables, or classes to the program. These can be used directly.
Differences between static and dynamic libraries:
(1) Both static and dynamic libraries share code. The static Link Library includes all the final commands in the final generated EXE file. The dynamic link library does not need to be included in the final EXE file, when executing an EXE file, you can dynamically reference and uninstall the DLL file that is independent from the EXE file.
(2) The static Link Library cannot contain any other dynamic or static Link Library, but other dynamic or static link libraries can be included in the dynamic link library.
Classification of Dynamic Link Libraries: Visual C ++ supports three types of DLL, which are non-mfc dll (non-MFC dynamic library) and MFC regular DLL (MFC rule DLL) and MFC extension DLL (MFC extension DLL ). The non-MFC dynamic library does not adopt the structure of the MFC class library. Its export function is a standard C interface and can be called by applications written by non-MFC or MFC; the MFC rule dll contains a class inherited from cwinapp, but it does not have a message loop. The MFC extension DLL is created using the dynamic link version of MFC, it can only be called by applications written in the MFC class library.
2. Create a DLL
2.1 Non-MFC DLL
2.1.1 declare the export function:
Extern "C" _ declspec (dllexport) int add (int A, int B );
Here, extern "C" is declared as C compilation. The C ++ compiler will change the function name during compilation, and the function cannot be called in other applications. The C compiler will not change the function name after compilation. In this way, if you use a C-compiled program to call the function in the DLL, the function may not be found.
_ Declspec (dllexport) indicates that this function is a DLL output function, that is, other applications can call this function.
There are two ways to declare an output function from a DLL:
(1) Another method is to use the module definition (. Def) file declaration. The. Def file provides the linker with information about export, attributes, and other aspects of the linked program.
(2) Use _ declspec (dllexport) to declare a function
If visual C ++ is used to create a DLL, it is no problem to call the DLL for an EXE created using VC. If you use an EXE created by other tools to call the DLL, the problem may occur. Because even if you don't use the C ++ compiler, the Microsoft C compiler will damage the C function. When _ stdcall is used to output a function, the C compiler will change the function to [email protected. Add the exports section to the. Def file to output the function:
Exports
Func
In this way, DLL uses the func function name to output the function.
Another way is to use # pragma (linker, "/exports: [email protected]") to tell the compiler to output the function func, which is better than the previous one.
If a DLL written in VC ++ is to be called by a program written in other languages, the function call method should be declared as _ stdcall. winapi adopts this method, the default call method of C/C ++ is _ cdecl. The _ stdcall method is different from the _ cdecl method for generating symbols for function names. If the C compilation method is used (the function must be declared as extern "C" in C ++), __stdcall indicates that the name of the output function must be underlined, the "@" symbol is followed by the number of bytes of the parameter, for example, [email protected]. The _ cdecl call Convention only underscores the name of the output function, for example, _ functionname.
Lib. Def: the rule for exporting the DLL function library dlltestexportsadd @ 1. Def file is:
(1) The Library statement describes the DLL corresponding to the. Def file;
(2) Name of the function to be exported after the exports statement. You can add @ n after the export function name in the. Def file to indicate that the sequence number of the function to be exported is n (this sequence number will play its role during function calling );
(3) The annotation in the def file is specified by the semicolon (;) at the beginning of each comment line, and the comment cannot share a line with the statement.
In this example, the Lib. Def file is used to generate a dynamic link library named "dlltest", export the Add function, and specify the serial number of the add function as 1.
2.1.2 DLL call method:
There are two DLL calling methods: Dynamic and Static.
(1) dynamic call: typedef int (* lpaddfun) (INT, INT); // macro-defined function pointer type
Lpaddfun add; // function pointer
Hinstance hdll = loadlibrary ("path ");
Add = (lpaddfun) getprocaddress (hdll, "add"); // obtain the Add function pointer in the DLL
Freelibrary (hdll );
The functions, pointers, or classes returned from the DLL call are all pointer-based, that is, the return is the address of the function, variable, or class. Note that the function name cannot be used to assign values.
(2) Static call: Upload the generated. dll and. Lib files to the project that calls the DLL and use the command
# Pragma comment (Lib, "dlltest. lib ") to implement static calls, that is, compile the DLL into the EXE file during compilation, and then use the following code when calling the project:
# Pragma comment (Lib, "dlltest. lib ")//. the LIB file only contains the relocation information about the functions in the corresponding DLL file. extern "C" _ declspec (dllimport) add (int x, int y); int main (INT argc, char * argv []) {int result = add (2, 3); printf ("% d", result); Return 0;} as can be seen from the above Code, two actions are required for the smooth execution of the static call method: (1) Tell the compiler to correspond to the DLL. path and file name of the Lib file, # pragma comment (Lib, "dlltest. lib.
When a programmer creates a DLL file, the connector automatically generates a corresponding one. lib file, which contains the symbolic name and serial number of the DLL export function (excluding the actual code ). In an application, the. Lib file is used as a DLL replacement file for compilation.
Another explicit call method is to set the Directory and includefiles in VC to implement
(2) declare the import function. The _ declspec (dllimport) in the extern "C" _ declspec (dllimport) add (int x, int y) Statement plays this role.
The static call method does not need to use system APIs to load or uninstall the DLL and obtain the address of the exported function in the DLL. This is because, when programmers compile an application through static links. function symbols matching the exported characters in the Lib file will enter the generated EXE file ,. the file name of the corresponding DLL file contained in the Lib file is also stored in the EXE file by the compiler. 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 to implement dynamic links to the DLL function. In this way, exe can directly call the DLL output function through the function name, just like calling other functions in the program.
2.1.3 dllmain Function
When Windows loads a DLL, it first needs an entry function dllmain. When dllmain is not defined in DLL, Windows calls a dllmain function that does not perform any operation from other runtime libraries and returns true directly. Dllmain is the internal function of the DLL, which means that it cannot be explicitly called in the program that calls the DLL. It is automatically called when the DLL is called.
Bool apientry dllmain (handle hmodule, DWORD ul_reason_for_call,
Lpvoid lpreserved)
{
Switch (ul_reason_for_call)
{
Case: dll_process_attach:
Break;
Case: dll_thread_attach:
Break;
Case: dll_thread_detach:
Break;
Case: dll_process_detach:
Break;
Return true;
}
}
2.2 export variables in DLL
1. Define the variable extern int global in DLL;
2. Define Output Exports in. Def:
Global Data
3. Call: # pragma comment (Lib, "dlltest. lib") in the application ")
Extern int global;
Note that the global variable introduced here is an address, which must be forcibly converted to a pointer before being used to obtain its value.
(Int *) Global = 10;
A better way to reference global variables in DLL in an application project is:
Extern int _ declspec (dllimport) Global; // use _ declspec (dllimport) to import
The _ declspec (dllimport) method imports the global variables in the DLL instead of their addresses. We recommend that you use this method whenever possible.
2.3 DLL export class
Use class _ declspec (dllexport) classname {
}
Use
Add the class definition header file: # include "classname. h"
Class _ declspec (dllimport) classname to import classes
3. MFC rule DLL
The concept of the MFC rule DLL is embodied in two aspects:
(1) It is an MFC
"Yes. MFC" means that you can use MFC within such a DLL;
(2) It is rule-based
"Yes" means that it is different from the MFC extension DLL. Although MFC can be used within the MFC rule DLL, its interface with the application cannot be MFC. The interface between the MFC extension DLL and the application can be MFC, and a derived class of the MFC class can be exported from the MFC extension DLL.
Regular dll can be called by all applications written in languages that support DLL technology. Of course, it also includes applications that use MFC. This dynamic Connection Library contains a class inherited from cwinapp, And the dllmain function is automatically provided by MFC.
(1) Static link to the MFC rule DLL
Static links to the MFC rule DLL and the MFC Library (including the MFC extension DLL). The Code of the MFC Library is directly generated in the. dll file. When calling this DLL interface, MFC uses DLL resources. Therefore, you do not need to switch the module status in the Rule DLL that is statically linked to MFC.
The rule DLL generated using this method has a large program and may contain duplicate code.
(2) dynamic link to the MFC rule DLL
The rule DLL that dynamically links to MFC can dynamically link to the mfc dll and any MFC extension DLL together with its executable files. When the MFC shared library is used, by default, the MFC uses the resource handle of the main application to load the resource template. In this way, when the DLL and application have resources with the same ID (that is, the so-called resource repetition problem), the system may not be able to obtain the correct resource. Therefore, for the rule DLL that shares the mfc dll, We must switch the module so that MFC can find the correct resource template.
In Visual C ++, we can set whether the MFC rule DLL is statically linked to the mfc dll or dynamically linked to the mfc dll. 8. Select project> Settings> general menu or option of Visual C ++, and set it in Microsoft Foundation Classes.
3.1 create a rule DLL;
Unlike non-mfcdll, the MFC class can be introduced in its definition, and the others are the same as those in non-MFC.
3.2 call of Rule DLL
(1) display mode loadlibrary, getprocadress, freelibrary
(2) We can call the MFC rule DLL implicitly in the EXE program, just generate the DLL project. lib file and. DLL files are written to the directory where the current project is located and stored in regulardllcalldlg. add at the top of the CPP file (implementation file of the dialog box class shown in figure 12:
# Pragma comment (Lib, "regulardll. lib ")
3.3 switch the module of the Rule DLL that shares the MFC DLL
The application process itself and each DLL module it calls have a globally unique hinstance handle, which represents the starting address of the DLL or EXE module in the process virtual space. The module handle of the process is generally 0x400000, and the default handle of the DLL module is 0x10000000. If the program loads multiple DLL files at the same time, each DLL module has a different hinstance. When the application loads the DLL, It is relocated.
The rule DLL that shares the mfc dll (or the MFC extension DLL) involves the hinstance handle issue. The hinstance handle is particularly important for loading resources. Both EXE and DLL have their own resources, and the IDs of these resources may be repeated. The application needs to find the correct resource by switching the resource module. If the application needs DLL resources, you should specify the resource module handle as the DLL module handle. If you need resources contained in the EXE file, the resource module handle should be specified as the module handle of exe.
There are three ways to switch between modules:
(1) Call afx_manage_state (afxgetstaticmodulestate () in the DLL function. (recommended) void showdlg (void) {// Method 1: change at the beginning of the function, restore the afx_manage_state (afxgetstaticmodulestate () at the end of the function; Use the afx_manage_state (afxgetstaticmodulestate () as the first // statement of the interface function to switch the module status to afx_manage_state ());
Cdialog DLG (idd_dll_dialog); // open the DLG. domodal () ;}( 2) Call afxgetresourcehandle (); afxsetresourcehandle (hinstance XXX) in the DLL function );
(3) switch from the application itself (not recommended, the most troublesome)
4. Extended mfcdll
The content of the MFC extension DLL is the extension of the MFC. You can use the MFC extension DLL just like using the DLL of the MFC itself. In addition to MFC extension DLL, the interface between the MFC extension DLL and the application can also be MFC. We generally use MFC extension DLL to include some enhanced functions of MFC, such as cstatic and cbutton extension of MFC to provide more powerful capabilities.
Export a class and use afx_ext_class directly in the class declaration header file. Do not forget to add the Class header file to the program that calls the DLL.
5. Summary:To sum up, the above DLL types are mainly different from the following: 1. The dynamic link library dynamically loads the EXE program during program execution, static link libraries are compiled in the code during compilation. 2. Dynamic Link Libraries can output variables, functions, and classes. The methods for each output are different from those for calling: (1) variable: Define extern int global in DLL. output exportsglobal data or extern _ declspec (dllexport) int global in the def file (No output file is needed). Call it in the program: static call: # pragma comment (Lib, "dlltest. lib ") extern int _ declspec (dllimport) Global; Dynamic call :( 2) function: Define extern" C "_ declspec (dllexport) int add (int, int B); you can also. def file output this function exportsadd @ 1 called in the program: static call: # pragma comment (Lib, "dlltest. lib ") extern" C "_ declspec (dllimport) add (int x, int y); Dynamic call: typedef int (* lpaddfun) (INT, INT ); // macro-defined function pointer type
Lpaddfun add; // function pointer
Hinstance hdll = loadlibrary ("path ");
Add = (lpaddfun) getprocaddress (hdll, "add"); // obtain the Add function pointer in the DLL
Freelibrary (hdll );
The functions, pointers, or classes returned from the DLL call are all pointer-based, that is, the return is the address of the function, variable, or class. Note that the function name cannot be used to assign values. (3) Class: defined in dll:
Use class _ declspec (dllexport) classname {
}
Use
Add the class definition header file: # include "classname. h"
Class _ declspec (dllimport) classname to import classes
3. In addition to the extended mfc dll, other dll can be called by applications written in other languages.
DLL concept, DLL export class (resend)