Http://www.zahui.com/html/1/1687.htm
Deep understanding of dynamic libraries
I. Usage of dynamic Connection Library
Dynamic Connection Library, dynamic-Link Libraries (DLL), is a software technology provided by Microsoft. It is essentially an executable module that contains some functions and data. It can be applied Program (. EXE) or other DLL calls. This technology has the following benefits: resource sharing, memory saving, multi-language support, reusable, and convenient development of large projects. This is not a bit old-fashioned. It is also true that textbooks all have it. Cough, it's time to review your lessons ....
The following is my understanding.
Without summary, there will be no progress. Who said this. As a carrier, it is used to summarize past experiences, and the dynamic library is advantageous. For example, you have accumulated a lot of experience, skills, and ideas in previous project development or programming (?) And professional materials, and they are valuable in specific fields. However, with the development of development tools and the upgrade of the execution platform, these experiences, skills, and materials may be discarded. As a summary of the previous Labor achievements, they are collected into a specific dynamic library, which is a two-way solution.
Beautiful method. Because the dynamic library and Programming Language Unrelated, so that the resources can be more widely used. As a long-term consideration, the reuse of resources not only does not waste the previous work, but also increases the value of the original work and makes the work more effective. In particular, the reuse of resources. If software reuse is systematically considered, it is a solution to the repetitive labor problem in software development. Dynamic library is a way and method. Based on existing work, make full use of the accumulated knowledge and experience in application system development in the past, and focus on application development.
Eliminate repetitive work, avoid possible errors introduced by redevelopment, and improve the efficiency and quality of software development.
In addition, as a special case of mixed programming, dynamic libraries are not allowed. Because the dynamic library has nothing to do with a specific programming language, as long as the language supports the dynamic library technology, this language can be used for the purpose of "learning from each other ". The existence of various programming languages is due to their respective strengths. We can use a dynamic library to split a large task into subtasks, which can be implemented in different languages.
Another example is Microsoft's application interface API.
Ii. dynamic database connection conventions
There are two types of conventions for dynamic library output functions: Call conventions and name modifiers.
The call conventions determine the order of incoming and outgoing stacks when function parameters are transferred, and the modifiers used by the compiler to identify function names. The name modification conventions vary with the call conventions and compilation types (C or C ++. To make it easier for different programming languages to share the dynamic library, the correct call conventions must be used for function output, and it is best not to include any name modifier generated by the compiler. The following uses vc5 and vb5 as examples to describe how to implement these requirements.
(1) Call conventions
there are multiple function call conventions supported by VC ++ 5.0. Here we only discuss the following three types: __stdcall, C, and _ fastcall.
the _ stdcall call convention is equivalent to the Pascal call convention that is frequently used in 16-bit dynamic libraries. In 32-bit VC ++ 5.0, Pascal's call Convention is no longer supported (in fact, it has been defined as _ stdcall. In addition to _ Pascal, __fortran and _ syscall are not supported). Instead, they are replaced by the _ stdcall call convention. The two are essentially the same, that is, the function parameter is passed from right to left through the stack. The called function clears the memory stack of the transfer parameter before returning, but the difference is the function name modifier section (the modification section of the function name will be described in detail later ).
the C call conventions (that is, descriptions using the _ cdecl keyword) and the _ stdcall call conventions are different. Although the parameter transfer Conventions are the same, however, the memory stack of the transfer parameter is maintained by the caller (because of this, the function that implements the variable parameter can only use this call Convention). In addition, the function name modification conventions are also different.
_ fastcall: The call convention is "person" as its name. Its main feature is fast because it transmits parameters through registers (in fact, it uses ECx and EDX to transmit the first two dual-character or smaller parameters. The remaining parameters are still transmitted from right to left, the called function clears the memory stack of the transfer parameter before returning). In terms of the function name modification conventions, it is different from the previous two.
the keywords _ stdcall, _ cdecl, and _ fastcall can be directly added before the function to be output, or in the setting environment... select \ C/C ++ \ code generation. When the keywords added before the output function are different from those selected in the compiling environment, the keywords directly added before the output function are valid. Their corresponding command line parameters are/GZ,/GD, And/GR. The default status is/GD, Which is _ cdecl.
By the way, to fully imitate Pascal's call convention, you must first use the _ stdcall call Convention. As for the function name Modification Convention, you can use other methods to imitate it. Another thing worth mentioning is winapi macro, windows. h supports this macro. It can translate the output function into an appropriate call convention. In Win32, it is defined as _ stdcall.
Suggestion: Use the winapi macro so that you can create your own APIs.
(2) function name modification conventions
The function name modification conventions vary with the compilation type and call conventions.
For C compilation, the _ stdcall call Convention adds an underline prefix before the output function name, followed by a "@" symbol and the number of bytes of its parameter, in the format of _ functionname @ number. The _ cdecl call Convention only adds an underline prefix before the output function name in the format of _ functionname. _ Fastcall: add the "@" symbol before the output function name, followed by the "@" symbol and the number of bytes of the parameter. The format is @ functionname @ number. They do not change the username in the output function name.
The calling conventions are different. Pascal conventions do not modify the name of the output function and all functions are capitalized. Here, I provide a method that completely imitates Pascal's call conventions. It is implemented through ALIASES IN THE exports segment of the. Def file. For example:
Int _ stdcall myfunc (int A, double B );
Void _ stdcall initcode (void );
In the. Def file:
Exports
Myfunc = _ myfunc @ 12
Initcode = _ initcode @ 0
The name modification of the function compiled and output by C ++ is complex, and is not described in the random document of VC ++ 5.0. After some experiments and exploration, I found that the naming conventions for function name modification during C ++ compilation are described as follows.
_ Stdcall call conventions:
1. Take "?" Start of the function name, followed by the function name;
2. The parameter table starts with "@ YG" after the function name, followed by the parameter table;
3. The parameter table is represented in 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 -- indicates the pointer. The code behind the pointer indicates the pointer type. If the pointer of the same type continuously exits, it is replaced by "0". A "0" indicates a repetition;
4. the first item of the parameter table is the type of the return value of the function, followed by the Data Type of the parameter;
5. mark the end of the entire name with "@ Z" after the parameter table. If this function has no parameter, it ends with "Z.
The format is "? Functionname @ YG ***** @ Z "or"? Functionname @ YG * xz ", for example
Int test1 (char * var1, unsigned long) ----- "? Test1 @ yghpadk @ Z"
Void Test2 () ----- "? Test2 @ ygxxz"
_ Cdecl:
The rules are the same as the _ stdcall call Convention above, except that the start mark of the parameter table is changed from "@ YG" to "@ ya ".
_ Fastcall call Convention
The rules are the same as the _ stdcall call Convention above, but the start mark of the parameter table is changed from "@ YG" to "@ Yi ".
(3) Get the unmodified function name
When VC ++ outputs a function, _ declspec (dllexport) is used instead of the _ export modifier.
_ Declspec (dllexport) removes the underline prefix of the output function name in the case of C call conventions and C compilation. Extern "C" makes it possible to use the C compiling method in C ++. In a C ++ file, use extern "c" to indicate that the function uses the C compiling method. For example, a C ++ file contains the following functions:
Extern "C" {void _ declspec (dllexport) _ cdecl test (INT var );}
The output function is named test.
For convenience, you can use the following preprocessing statements:
# If defined (_ cplusplus)
Extern "C"
{
# Endif
// Function prototype description
# If defined (_ cplusplus)
}
# Endif
In this case, after special processing, a function name without any modification can be obtained in both C and C ++.
Next we will introduce another way: Use the. Def file to output the function instead of the _ declspec (dllexport) modifier output function. The modifier name to be output must be listed under exports. This name must be exactly the same as the name of the defined function. In this way, a function name without any modifier is obtained.
At this point, we have at least three methods to get "function names without any modifier.
I mentioned at the beginning that "function output without any name modifier generated by the compiler" is particularly important in multilingual mixed programming.
(4) Experiment
Next we will make an experiment to help you better understand the content described above.
Experiment idea: There is a software system that uses vb5 to design its interface and uses vc5 to write a dynamic library for tedious computing, some intermediate results should be displayed in the calculation process. vb5 is used to complete the display task. Therefore, a display function is defined in vb5 and is called back and forth by the dynamic library, and the calculation result is used as the callback parameter ....
first, use vb5 to compile the interface and define the display function. Create a project, add a module file, and define our display function (callback function) in the module File:
Public sub showresult (result as long)
form1.print result 'is displayed in a simple simulation.
end sub
In addition, the dynamic library output function is described as follows:
declare sub testshow lib "test32.dll" (byval show as long, Param as any)
, put a command button on the form and add the following Code :
private sub command1_click ()
dim I as long
testshow addressof showresult, I
end sub
Now we use vc5 to write our dynamic library.
Create a project. Select New Projects | Win32 dynamic-Link Library, enter the project name test32, and add the following content to the. cpp file:
# Include <windows. h>
Bool winapi dllentrypoint (hinstance hinstdll, DWORD fdwrreason,
Lpvoid plvreserved)
{
Return 1; // indicate that the DLL was initialized successfully.
}
Void testshow (INT appshow (int *), int * flag)
{
For (INT I = 0; I <10; I ++)
{
* Flag = 11011 + I; file: // For the sake of simplicity, here the result of "complex calculation" is replaced by a direct value assignment.
Appshow (FLAG); file: // callback
}
}
Here we use the. Def file output function. Add the following content to the. Def file:
Library test32
Description 'test32. dll'
Exports
Testshow @ 1
Set the call convention to _ stdcall, compile and generate test32.dll, and export it to the system directory.
Finally, run the vb5 project compiled above. OK ?!
Experiment 1: Change the call convention to the default setting, that is, the C call Convention. If the others remain unchanged, re-compile and generate test32.dll and export it to the system directory. Test the vb5 project to see it ......
Experiment 2: Change the call convention to the default setting, that is, the C call Convention. Add the _ stdcall keyword or winapi macro before the testshow function, recompile and generate test32.dll and import it to the system directory. Test the vb5 project ......
Experiment 3: Change the call convention to the default setting, that is, the C call Convention. Add the _ stdcall keyword or winapi macro before the testshow function, add the _ stdcall keyword before the first appshow parameter.
Void _ stdcall testshow (INT _ stdcall appshow (int *), int * flag)
Recompile and generate test32.dll and import it to the system directory. Test the vb5 project ......
Tip: vb5 function calls follow the API call conventions (_ stdcall, that is, the original Pascal ).
For more information about the concepts and conventions of callback functions, see related books.
Iii. parameter transfer
The parameter passing of the output function of the Win32 dynamic library is also described above, which is further described here. In a 32-bit dynamic library, all parameters are extended to 32-bit (such as struct parameters and short Integer Parameters) and pushed from right to left to the stack. The Return Value of the function is also extended to 32 bits in the eax register, and the 8-byte return value is placed in the edX: eax register pair, when the returned value is a larger structure, eax is used as a pointer to the invisible return structure. When a function uses related registers (such as ESI, EDI, EBX, and EBP), the compiler automatically generates a function header and a function tail for saving and restoring these registers. The following is an example of parameter transfer. We already know that the parameter passing conventions of __stdcall and _ cdecl are the same, and __fastcall call conventions are different from them.
Void myfunc (char C, short S, int I, double F );
.
.
.
Void myfunc (char C, short S, int I, double F)
{
.
.
.
}
.
.
.
Myfunc ('A', 22,819 2, 2.1418 );
The parameter transmission during execution is as follows:
_ Stdcall and _ cdecl call conventions
Location Stack
ESP + 0x14 2.1418.
ESP + 0x10
ESP + 0x0c 8192
ESP + 0x08 22
ESP + 0x04
ESP Return Value
_ Fastcall call Convention
position stack
ESP + 0x0c 2.1418
ESP + 0x08
ESP + 0x04 8192
ESP return value