Preface: This is a summary of the article, need to have a little C + + and DLL basic knowledge of the foundation, in the online access to a lot of information feel not a detailed, specific, comprehensive DLL development introduction, I This is based on recent projects and online data collated out, And comes with an example of a summary of the article (because of the length of the reason does not come with source interpretation). In addition, the individual is foolish to think that the development of C + + will be more oriented to the development of libraries, so the development of library is essential.
1. Static link library and dynamic link library
1. The Static link library (LIB) is used only during program development, while dynamic-link libraries (DLLs) are used during execution.
2. Another difference between a static-link library and a dynamic-link library is that the static-link library can no longer contain other dynamic-link libraries or static libraries, and other dynamic or static link libraries may be included in the dynamic-link library.
3. Static link library, waste space and resources, because all the relevant target file and the involved library is linked to the composition of an executable file. Another problem is that static libraries can cause problems with updating, deploying, and publishing pages for programs. If the static library Libname.lib is updated, all applications that use it need to be recompiled, published to the user (a small change for the user, which causes the entire program to be re-downloaded, and the whole volume updated).
4. The dynamic library realizes the increment update, the process can share the dynamic library, saves the resources, when the program first calls the dynamic library, the system loads the library into memory, when another program also calls this library, the system no longer loads, but the state +1, when a program exits or releases the library, the state is-1, The system automatically cleans up and frees memory until a program in the system calls the library.
2, Knowledge points
1. There are 2 types of class libraries created in VS, one of which is to directly select VC + + Class library (which is a class library created using Microsoft version C + +), a Win32 project or WIN32 console program, and then select the corresponding class library type, which is the ANSI standard C + + class library. In general, we create the class library in this way, and it is divided into three kinds: NON-MFC DLL (non-MFC dynamic Library), MFC Regular DLL (MFC regular DLL), MFC Extensiondll (MFC extension DLL).
2. Non-MFC dynamic library does not adopt the MFC class library structure, its export function is the standard C interface, can be called by non-MFC or MFC-written applications; the MFC rule DLL contains a class that inherits from CWinApp, but has no message loops; The MFC extension DLL is created with the dynamic Link version of MFC. It can only be called by an application written by the MFC class library.
3. When Windows wants to execute a program that uses a dynamic-link library and needs to load the link library, the dynamic-link library file must be stored in the containing. EXE program, under the current directory, under the Windows System directory, in the Windows directory, or in a directory that can be accessed through path in the MS-DOS environment (Windows searches for these directories sequentially).
4. The dynamic link library module may have other extensions (such as. EXE or. FON), but the standard extension is. DLL. Only band. DLL extension can be automatically loaded by Windows. If the file has a different extension, the program must also load the module using the LoadLibrary or LoadLibraryEx function.
5. DLL compilation is independent of the specific programming language and compiler. DLLs written in various languages can call each other as long as they follow the agreed specification and invocation of DLL interfaces.
3. Key words
1. When a DLL is created, it should contain all functions that handle both Unicode and non-Unicode versions of characters and strings, such as implementing ANSI and wide-character editions.
#ifdef unicode#define TEXTW //define wide-character version of the function #else#define texta //define the ANSI version of the function #endif
2. __declspec (dllexport), which is in the declaration and definition of a class/function, indicates that the class/function is an exported class/function for a DLL. and the class/function inside the DLL is divided into two kinds, one is DLL export class/function for external program call, one is DLL internal function for DLL to call.
3. __declspec (dllimport), the keyword stating that the class/function is an import function, corresponds to the __declspec (dllexport) match, in order to use its declared class/function in the application.
4. extern "C" is to solve the problem of exporting the function name, because the C + + compiler, in order to implement the function overload, in the compiled generated assembly code to do some processing of the function name, and the extern "C" declaration of the function will use the function name, then c processing mode. Therefore, only non-member functions can be declared as extern "C" and cannot be overloaded. However, with the extern "C" qualifier, it does not mean that C + + code is not available in the function, but instead it is still a complete C + + function that can use any C + + attributes and various types of parameters. But this only solves the problem of calling between C + + +, and a more reliable way is to define a. def file.
5. __cplusplus, which is a custom macro in CPP, defines that this macro represents a piece of CPP code. And this is a macro definition reserved by the C + + compiler, meaning that the C + + compiler thinks the macro is already defined.
If the function is defined like this: extern "C" int add (int a, int b); because the C compiler does not recognize the extern "C" directive, C calls a C + + program with a problem, and __cplusplus is in effect. As follows:
#ifdef __cplusplusextern "C" {#endif//.... Claim code #ifdef __cplusplus} #endif
6. #pragma comment (lib, ". Debug//libproject.lib ") means that the. obj file generated by this file (application) should be connected with LIBProject.lib.
7. __stdcall, which is the abbreviation for standard calls, is the normal function call method of C: All parameters are in the stack from right to left, and if the class member is called, the last one to stack is the this pointer. The parameters in the stack are cleared by the called function after it is returned, and the function must strictly control the parameter generation at compile time, otherwise it will be returned with an error.
8. __fastcall, which is a fast-calling method specified by the compiler. Since it is time-consuming to use the stack pass, the __fastcall usually specifies that the first n (typically 2, different compilers specify the number of registers used) parameters are passed by the CPU register, and the rest is passed with the memory stack. The return method is equivalent to __stdcall. Because it involves the compiler to decide how to pass the parameters, it cannot be used as a cross-compiler interface.
9. __cdecl, which is the abbreviation for C declaration, represents the default function call method for C: All parameters are entered in the stack from right to left, the parameters are purged by the caller (manually cleared, the caller generally refers to the compiler). The feature is that you can use an indefinite number of parameters.
If the DLL written by VC + + is called by a program written in another language, the function should be called in __stdcall mode, and the C + + default Call method is __cdecl (the default method). The difference between __stdcall and __cdecl is in the way that the final symbol of the function name is generated. In the case of C compilation (the function is declared as extern "C" in C + +), the __stdcall convention is preceded by an underscore in the output function name, followed by the "@" symbol and the number of bytes of the parameter, such as [email protected]; __ The CDECL convention is underlined only in front of the output function name, as in the form of _functionname.
Note that the Declaration function form: extern "C" int __stdcall Add (int x, int y);, the function pointer in the application is: TypeDef int (__stdcall *lpaddfun) (int, int);
4. Static library (LIB/A)
Since the static library is connected to the source file (EXE) along with the application, the code is not written in any particular way, and it is important to note that extern "C" is used to determine whether to compile using C, and then to use #ifndef to manage the invocation of a class/function of a type.
Notable is the declaration of the use of static libraries in the application # include "MathTool.h", #pragma comment (lib, "LIBProject.lib") : It seems impossible to put the. h and. lib files directly in the current directory (not for my tests), two methods: 1. Use relative or absolute paths to include. h and. lib files. 2. Specify the file directory for the. h through "Properties"--"C + +"--"general"--"additional Include Directories". Add the. lib directory through the properties--linker--general--Attach library directory. This method also applies to dynamic libraries.
If you do not want to specify Lib with #pragmacomment, you can also specify the library in the properties--linker--general--additional dependent libraries. Instead of setting the library directory and relying on the library name, you can enter the full path to the static library by directly "properties"--"linker"--"command line". But generally not recommended.
See Example: Libproject.
5. Dynamic library (DLL/SO)
1. lib files for dynamic libraries and LIB files for static libraries
The lib file corresponding to the static library is called the Static library, and the lib file corresponding to the dynamic library is called the import library. In fact, the static library itself contains the actual execution code, symbol table and so on, and for the import library, its actual execution code is located in the dynamic library, the import library contains only the address symbol table, etc., to ensure that the program to find some basic address information of the corresponding function.
2. Declaring the Export function (introduction. def)
There are two ways to declare a DLL-exported function: One is to add __declspec (dllexport) to the Declaration; One is to use a module definition (. def) file declaration: the. def file provides the linker with information about the exported, attributes, and other aspects of the linked program.
The rules for. def files are:
(1) The library statement describes the corresponding DLL for the. def file;
(2) The name of the function to be exported is listed after the exports statement. You can add @n to the exported function name in a. def file to indicate that the ordinal of the function to be exported is n (the sequence number will play its role when the function call is made);
(3) The comments in the. def file are separated by a semicolon at the beginning of each comment line (;) specified, and the comment cannot share a row with the statement.
getinstance = getinstance The name of the function that can specify the DLL after export is still unchanged.
Note: Use a. def file to remember to set the DEF file in the compiler: "Properties"--"linker"--"Input"-"module definition file".
If you use __declspec (dllexport) to declare the export, it is certainly not a problem to use it in C + +, but when other languages (C #, VB) are called, there is a case where the function name cannot be found because the function name is changed in C + + for implementing overloading mechanism. This is the way we use the extern "C" + __declspec (dllexport) +__stdcall in order to make the correct calls to other languages. The use of DEF files can not be used, this is more convenient, but the use of the place of the class is to use the first way.
3. Invocation mode
There are two ways to call a DLL: one is dynamic, and one is a static call.
Dynamic Invocation : It is entirely up to the programmer to load and unload the DLL with API functions, and the programmer can determine when the DLL file is loaded or not loaded, and the explicit link at run time determines which DLL file to load. The Trinity "DLL load-dll function address gets-dll released" mode provided by the Loadlibrary->getprocaddress->freelibrary system API.
Where dynamic calls are noted, precede the function with extern "C" or define a def file. It is dangerous and cumbersome to explicitly call classes in a class library, so it can be implicitly non- explicit and static and non-dynamic .
static invocation: It is characterized by the compiler's completion of loading the DLLs and unloading the DLLs at the end of the application. Static call Mode when the application that calls a DLL ends, if there are other programs in the system that use the DLL, the Windows application record for the DLL is reduced by 1 until all programs that use the DLL are finished. When a programmer compiles a build application by statically linking, the function symbols that are called in the application that match the exported symbols in the. lib file are entered into the generated EXE file, and the file name of the corresponding DLL file contained in the. lib file is also stored inside the exe file by the compiler. When a DLL file needs to be loaded while the application is running, Windows will discover and load the DLL based on that information, and then dynamically link the DLL functions with symbolic names. In this way, EXE will be able to call the DLL's output function directly from the function name, just like other functions inside the calling program. Static invocation is a simple and practical method, but not as flexible as dynamic invocation.
A static call takes two steps:
1. Tell the compiler the path and file name of the. lib file that corresponds to the DLL, #pragma comment (lib, "DllTest.lib"). When a programmer builds a DLL file, the connector automatically generates a corresponding. lib file that contains the symbolic name and ordinal number of the DLL's exported function (which does not contain the actual code). In the application, the. lib file participates in the compilation as an alternate file for the DLL. Specifically, you can do this by copying the. h,. lib,. dll files to the current directory of the client program, and then #include<*.h> + #pragmacomment (lib, "DllTest.lib") in the program; Or the introduction of the Lib file is added to the project properties of the client program.
2. Declare the import function, using __declspec (dllimport) as the import function. It is sometimes not declared, and is defined during the writing of the class library.
4. DllMain function
When Windows loads a DLL, it needs an entry function, just as a console or DOS program requires the main function, and the WIN32 program needs the WinMain function. When the DllMain function is not written in the program, the system introduces a default version of the DllMain function from the other runtime that does nothing, and not the DLL can discard the DllMain function.
According to the writing specification, Windows must find and execute the DllMain function in the DLL as the basis for loading the DLL, which allows the DLL to remain in memory. This function is not an export function, but a DLL's intrinsic function. This means that the DllMain function cannot be referenced directly in the application, and DllMain is automatically called.
The DllMain function is called when the DLL is loaded and unloaded, and the DllMain function is called when a single thread starts and terminates, Ul_reason_for_call indicates the reason for the call.
BOOL apientry DllMain (hmodulehmodule, 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: Break ; } return TRUE;}
Analytical:
Apientry is defined as __stdcall, which means that the function is invoked in the form of standard Pascal, which is the WINAPI mode;
Ul_reason_for_call the four parameters Dll_process_attach represents a process call; Dll_thread_attach represents a thread invocation; Dll_thread_detach thread release; Dll_process_detach thread release.
lpreserved is a reserved word, basically no role, no need to understand.
Each DLL module in the process is identified by a globally unique 32-byte hinstance handle, which is valid only within a particular process, and the handle represents the starting address of the DLL module in the process virtual space. In Win32, the values of hinstance and hmodule are the same, and the two types can be substituted for use, which is the origin of the function parameter hmodule.
GetProcAddress (hDLL, Makeintresource (1)) Note that it accesses the add function directly through the sequence number specified in the. def file for the Add function, as shown in Makeintresource (1), Makeintresource is a macro that gets the function name by ordinal, defined as (excerpt from Winuser.h):
#defineMAKEINTRESOURCEA (i) (LPSTR) (DWORD) ((Word) (i)) #defineMAKEINTRESOURCEW (i) (LPWSTR) ((DWORD) ((Word) (i))) # ifdef Unicode#definemakeintresource Makeintresourcew#else#definemakeintresource MAKEINTRESOURCEA
5. DLL Export variables
The global variables defined by the DLL can be accessed by the calling process, and the DLL can access the global data of the calling process. Steps:
1. The header file of the library, declared in H, extern int dllglobalvar;
2. Declared in. cpp file, declaration: int dllglobalvar; using: Dllglobalvar = 100;
3. def file to export, "[email protected][n]" way, some people say is Dllglobalvar CONSTANT (OBSOLETE)/Dllglobalvar data this way, but I do not use.
4. There are two ways to reference global variables defined in a DLL in your application: One method (a variable declared with Def): first declares an extern int dllglobalvar, and then int a = * (int*) Dllglobalvar. It is important to note that the Externint Dllglobalvar declaration does not import the global variable itself in the DLL, but its address. Another method: Externint _declspec (dllimport) Dllglobalvar; Importing through _declspec (dllimport) is the global variable itself in the DLL and is no longer its address. Suggested the second way, the first way I encountered some very strange problems in the test. Hope, someone based on my test, help me to solve the next.
See Example: DLLPROJEC
6. DLL Export class
Exporting classes, we generally use static calls so that we can export the entire class, or only the specified members of the class. If you use dynamic invocation classes, we typically use a global function to return an object of a class.
Finally, learning here, the greatest insight is that the class library, the main understanding of the extern "C", _declspec (dllexport), _declspec (dllimport), __stdcall, __cdecl these basic key words, Class libraries are provided for others, and all I need to do is specify which classes or functions to use for the user. There is also the use of class libraries to know static calls and methods of dynamic invocation.
See Example: DLLPROJEC
Attached Source Link: http://download.csdn.net/detail/z702143700/8738467
PostScript: This article is very long, but also I spent a lot of work days to learn the results of the practice, if there are errors or comments want to give me a message, combined with examples will be better, if you can directly read the example, then the long text can be casually browsed. Next, I'll describe the common methods that other languages call C + + class libraries (C # calls C + + libraries).
A detailed description of C + + class library development