DLL calls agreement and name modification
Calling Convention: means a protocol established in the programming language in order to implement function calls. This protocol specifies the parameter transfer mode in the function of the language, whether the parameters can be variable and who will handle the stack. Different languages define different call conventions.
In C , in order to allow operator overload and function overload, the C compiler often overwrites the symbol name of each entry point in accordance with some rules to allow the same name (having different parameter types or different scopes). A use method without breaking the existing C-based linker. This technique is often referred to as name mangling or name decoration (Name Decoration). Many C compiler vendors have chosen their name modification.
Therefore, in order to make the modules (such as Visual Basic Applications, Pascal or Fortran applications, such as Visual Basic applications, Pascal or Fortran applications, etc.), you must use the correct call agreement to export functions, and do not let the compiler Do any name modified for functions to be exported.
1. Calling convention
Call the convention to process the order of the stack and out of the stack when the determination function parameter is transmitted (the argument popping the argument popping arguments), and the compiler is used to identify the name modification of the function name. In Microsoft VC 6.0, the following call agreements are defined, we will analyze them one by one by part:
1, __ cdecl
__cdecl is a call agreement for the default use of the C / C and MFC programs, or the __cdecl keyword can be manually specified when the function declaration is declared. When using the __cdecl convention, the function parameters are in the order from the right to left, and the parameter pop-up stack is made by the calling function to clean the stack. Therefore, functions that implement variable parameters can only be used to use this call. Since each of the functions of the __cdecl agreed, you need to include the code of the cleaning stack, the executable file size will be relatively large. __cdecl can be written _cdecl.
The following will be analyzed by a specific example:
Create a Win32 Console project in VC , named CDECL. The code is as follows:
INT __CDECL Add (Int A, INT B); // Function Declaration
void main ()
{
Add (1,2); // function call
}
INT __CDECL Add (INT A, INT B) // Function Implementation
{
Return (A B);
}
The disassembly code at the function call is as follows:
Add (1, 2);
Push 2; parameter from right to left in the stack, first press 2
Push 1; press 1
Call @ ilt 0 (add) (00401005); call function implementation
Add ESP, 8; Call the clear stack by the function
2, __ stdcall
__stdcall call convention is used to call the Win32 API function. When using the __stdcal convention, the function parameters are in the order from the right to left, and the function being called is fixed before returning the stack of the transfer parameter, and the function parameters are fixed. Since the function body itself knows the number of parameters passed, the called function can be directly cleaned up with a RET N instruction directly before returning to the stack of the passing parameters. __stdcall can write _stdcall. Or that example, will be replaced with __cdecl to __stdcall:
INT __STDCALL ADD (int A, int b)
{
Return (A B);
}
Function call disassembly code:
Add (1, 2);
Push 2; parameter from right to left in the stack, first press 2
Push 1; press 1
Call @ ilt 10 (add) (0040100F); call function implementation
Function implementation part of the disassembly code:
INT __STDCALL Add (int A, INT B)
Push EBP
MOV EBP, ESP
SUB ESP, 40H
Push EBX
PUSH ESI
Push EDI
Lea EDI, [EBP-40H]
Mov ECX, 10h
Mov Eax, 0cccccccch
Rep Stos DWORD PTR [EDI]
RETURN (A B);
MOV EAX, DWORD PTR [EBP 8]
Add Eax, DWORD PTR [EBP 0CH]
POP EDI
POP ESI
POP EBX
MOV ESP, EBP
POP EBP
RET 8; Qing stack
3, __ fastcall
__fastcall agres to be used in applications with very high performance requirements. __fastcall agre, put the two sizes of the function from the left to the left of the two sizes in the ECX and EDX registers, and the rest of the parameters are still transmitted from left to the left, and the function called before returning. Clean the stack of transfer parameters. __fastcall can write _fastcall.
It is still similar example. At this time, the function call is agreed to __fastcall, the number of function parameters increased:
INT __FASTCALL Add (int A, Double B, INT C, INT D)
{
RETURN (A B C D);
}
Compilation code for function call parts:
Add (1, 2, 3, 4);
Push 4; After two parameters from right to left in the stack, first press 4
Mov Edx, 3; put the Int type 3 into EDX
Push 40000000H; 2 2 Double Type 2
PUSH 0
MOV ECX, 1; put the int type 1 into ECXCall @ ilt 0 (00401005); call function implementation
Function implementation part of the disassembly code:
INT __FASTCALL Add (int A, Double B, INT C, INT D)
Push EBP
MOV EBP, ESP
SUB ESP, 48H
Push EBX
PUSH ESI
Push EDI
Push ECX
Lea Edi, [EBP-48H]
MOV ECX, 12H
Mov Eax, 0cccccccch
Rep Stos DWORD PTR [EDI]
POP ECX
MOV DWORD PTR [EBP-8], EDX
MOV DWORD PTR [EBP-4], ECX
RETURN (A B C D);
Fild DWORD PTR [EBP-4]
Fadd Qword PTR [EBP 8]
FIADD DWORD PTR [EBP-8]
FIADD DWORD PTR [EBP 10h]
Call __ftol (004011B8)
POP EDI
POP ESI
POP EBX
MOV ESP, EBP
POP EBP
RET 0CH; Qing stack
Keywords __cdecl, __ stdcall, and __fastcall can be added directly before the function you want to output, you can also select the setting environment of Setting ...-> C / C -> Code Generation item. Their corresponding command line parameters are / gd, / gz, and / gr. The default state is / gd, ie __cdecl. 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.
4, THISCALL
The Thiscall call agreement is the default call agreement of the non-static class member function in C . Thiscall can only be used by the compiler, there is no corresponding keyword, so it cannot be specified by the programmer. When using thisCall Convention, the function parameters are in the stack from the right to left, and the called function is returned to the stack of the transfer parameters before returning, but additionally parameters are transmitted through the ECX register: this pointer.
This example will define a class and define a member function in the class, the code is as follows:
Class Csum
{
PUBLIC:
Int Add (Int A, INT B)
{
Return (A B);
}
}
void main ()
{
Csum Sum;
Sum.Add (1, 2);
}
Function call part assembly code:
Csum SUM;
Sum.Add (1, 2);
Push 2; parameter from right to left in the stack, first press 2
Push 1; press 1LEA ECX, [EBP-4]; ECX stores this pointer
Call @ ilt 5 (CSUM :: Add) (0040100A); call function implementation
Function implementation part assembly code:
; Int Add (int A, int b)
Push EBP
MOV EBP, ESP
SUB ESP, 44H; Murate a 4Bytes space for storing this pointer
Push EBX
PUSH ESI
Push EDI
Push ECX
Lea Edi, [EBP-44H]
MOV ECX, 11h
Mov Eax, 0cccccccch
Rep Stos DWORD PTR [EDI]
POP ECX
MOV DWORD PTR [EBP-4], ECX
RETURN (A B);
MOV EAX, DWORD PTR [EBP 8]
Add Eax, DWORD PTR [EBP 0CH]
POP EDI
POP ESI
POP EBX
MOV ESP, EBP
POP EBP
RET 8; Qing stack
5, naked attribute
When the four calls described above, the compiler generates code to save the value in ESI, EDI, EBX, EBP registers, generate code recovery of these registers when exiting functions. For functions that define the Naked property, the compiler does not automatically generate such code, and you need to manually use the embedded assembly to control the stack management in the function implementation. Since the Naked property is not a type modifier, it must be used together with the __Declspec. The following code defines a function that uses Naked properties and its implementation:
__DECLSPEC (Naked) Func ()
{
INT I;
Int J;
_asm
{
Push EBP
MOV EBP, ESP
SUB ESP, __local_size
}
_asm
{
MOV ESP, EBP
POP EBP
RET
}
}
Naked attributes and this section are not large, please refer to MSDN for details.
6, WinApi
There is also a WINAPI macro that is worth mentioning, which can be translated into an appropriate call agreement for functions. This macro is defined in WINDEF.H. Here is some of the contents in WINDEF.H:
#define cdecl _cdecl # define WinAPI CDECL
#define callback __stdcall
#define winapi __stdcall
#define apientry WinApi
This shows that WinAPI, Callback, Apientry is likely to function.
2. Name Decoration
C or C functions are identified by the decorative name internally (compile and link). The modulation of the function is a string generated when the compiler is generated when the compile function is defined or the prototype. The compiler is modified to the function name when creating .Obj files. In some cases the name of the function is necessary, if the output is specified in the module definition file, the output C overload function, the constructor, the destructive function, and the C or C functions such as in the assembly code.
In VC , the function modification is determined by the compilation type (C or C ), a function name, a class name, a call agreement, a return type, and a number of factors, and more. The following is compiled, C compiled (non-class member functions) and C classes and its member functions.
1, C compile time function name modification
When a function is using the __cdecl call convention, the compiler only plus a downline prefix before the original function name, format is _functionName. For example: function int __cdecl add (int A, int b), after outputting: _ADD.
When a function is using the __stdcall call convention, the compiler adds a downline prefix before the original function name, and the number of bytes of @ symbols and function parameters is added, and the format is _functionName @ number. For example: Function INT __STDCALL ADD (INT A, INT B), is: _ADD @ 8 after output.
When the function is in the __fastcall call convention, the compiler plus one @ symbol before the original function name, and the later is the number of bytes plus a @ symbol and function parameters, the format is @ functionname @ number. For example: Function INT __FASTCALL ADD (INT A, INT B), after outputting: @ add @ 8.
The above changes will not change the case in the original function name.
2, C compile time function (non-class member function) name modification
When the function uses the __cdecl call convention, the compiler performs the following work:
1. Taking the beginning of the logo function name, then follow the function name;
2. The function name is started with the @@ ya identifier, and then returns the value and the parameter table;
3. When the return value of the function or the parameter is independent of the C class, the return value and the parameter table below:
B: Const
D: char
E: UNSIGNED Char
F: short
G: unsigned short
H: int
I: unsigned int
J: long
K: unsigned long
M: float
N: double
_N: bool
PA: Pointer (*, the subsequent code indicates the pointer type, if the same type of pointer continuously, in 0, one 0 represents a repetition)
PB: Const pointer
AA: Quote (&)
AB: const referenced
U: class or structure
V: interface
W4: ENUM
X: void
4. After the @@ ya identification, it is followed by the return value type of the function. Thereafter, the data type of the parameter is subsequently, the pointer identifies before the data is used. When the return value or parameter of the function is independent of the C class, it is in line with this rule, otherwise it will be processed according to 5, 6 rules;
5. When the function return value is a class or a class with constant, the return value is named:? A /? B V class name @@ (without plus). When the function return value is a pointer / reference, or a pointer / reference with the CONST nature, the return value is named: PA / AA or PB / AB V Class @@ (without adding number);
6. When the function parameter is a class, and the class used by this parameter has appeared (which is the same as the class used by the returns value or the class used by the previous parameter), the parameter type format To: V 1 @ (without plus sign). If the class used by this parameter does not appear, the parameter type format is: V class name @@ (without plus sign). When the function parameter is a pointer / reference, or when there is a Const property pointer / reference, the parameter type format is based on the above format, plus a representative pointer / reference type or a Const property pointer / Reference type identifier (PA / AA or PB / AB);
7. After the parameter table is identified with the end of the entire name, if the function does not have parameters, the z identity ends.
When a function is using the __stdcall call convention, the rule of the compiler works with the above __cdecl calls, but the start identification of the parameter table is changed from the @@ ya to @@ YG.
When the function is using the __fastcall call convention, the rules of the compiler work together with the above __cdecl call, just the start identification of the parameter table is changed from the @@ ya to @@ yi.
3, C compile class and its member function name modification
For exported C classes, only the __cdecl call convention can be used. During the compiler compile, the compiler will process the C class. Such as: class __declspec (dllexport) MyClass is processed as class myclass & myclass :: operator = (Class Myclass Const &). When the C compiler is modified to the C class, the compiler performs the following work:
1. Taking the beginning of the logo function name, followed by? 4 class name;
2. The class name is followed by @@ QAE identifies, which is fixed for the export class;
3. @@ qe behind the AAV0 @ abv0 @, ie reference type identifier AA V 0 (Identifier of repetitive classes) @ (without plus sign) and CONST nature reference AB V 0 (repetitive class) Identifier) @ (without plus sign); 4. Finally, with the @z identify the end of the entire name.
For members of the C class (non-configuration functions, and destructor), different calls can be used. When the member function in the exported C class uses the __cdecl call convention, the compiler performs the following work:
1. Taking the beginning of the logo function name, then follow the function name @ class name (without plus sign);
2. After the @@ QAE identification start, follow the return value and parameter table;
3. When the return value of the function or the parameter is independent of the C class, the return value and the parameter table below:
B: Const
D: char
E: UNSIGNED Char
F: short
G: unsigned short
H: int
I: unsigned int
J: long
K: unsigned long
M: float
N: double
_N: bool
PA: Pointer (*, the subunies indicate the pointer type, if the same type of pointer continuously, 0
Instead, a 0 represents a repetition)
PB: Const pointer
AA: Quote (&)
AB: const referenced
U: class or structure
V: interface
W4: ENUM
X: void
4, the @@ QAE identification followed by the return value type of the function, and then the data type of the parameter is subsequently, the pointer identifies before the specified data type. When the return value or parameter of the function is independent of the C class, it is in line with this rule, otherwise it will be processed according to 5, 6 rules;
5. When the function return value is the current class or the current class with const, the return value is named:? A or? B v 1 @@ (without plus sign). When the function returns the value of the current class / reference, or when the current class with the const nature, the return value is named: PA / AA or PB / AB V 1 @@ (without adding number);
6. When the function return value is a class or a class with const, the return value is named:? A /? B V Class @@ (without plus sign). When the function return value is a pointer / reference, or a pointer / reference with the CONST nature, the return value is named: PA / AA or PB / AB V Class @@ (without adding number);
7. When the function parameter is a class, and the class used by this parameter has appeared (that is, the class currently exported, the same as the class used by the function return value or the same class as the previous parameter) Class), the parameter type format is: V 1 @ (without plus sign). If the class used by this parameter is not the class currently exported, the parameter type format is: V class name @@ (without plus). When the function parameter is a pointer / reference, or when there is a Const property pointer / reference, the parameter type format is based on the above format, plus a representative pointer / reference type or a Const property pointer / Reference type identifier (PA / AA or PB / AB); 8, after the parameter table identifies the end of the entire name, if the function is not parameters, the z identity ends.
When a function is using the __stdcall call convention, the rule of the compiler works with the above __cdecl calls, but the start identification of the parameter table is changed from the @@ ya to @@ YG.
When the function is using the __fastcall call convention, the rules of the compiler work together with the above __cdecl call, just the start identification of the parameter table is changed from the @@ ya to @@ yi.
4, C compilation to export data, name modification
For exported data, only the __cdecl call convention is used. When the C compiler is modified to the C class, the compiler performs the following work:
1. Taking the beginning of the data, then follow the data name;
2. The data name begins with the @@ 3 identifier, followed by the data type;
3. When the data type is independent of the C class, the data type The following code indicates:
B: Const
D: char
E: UNSIGNED Char
F: short
G: unsigned short
H: int
I: unsigned int
J: long
K: unsigned long
M: float
N: double
_N: bool
PA: Pointer (*, the subunies indicate the pointer type, if the same type of pointer continuously, 0
Instead, a 0 represents a repetition)
PB: Const pointer
AA: Quote (&)
AB: const referenced
U: class or structure
V: interface
W4: ENUM
X: void
4. If the data type is a class, the data type is named: V class name @@ (without plus sign). When the data type is a pointer / reference, or a pointer / reference with a CONST nature, the data type is named: PA / AA or PB / AB V Class @@ (without plus sign );
5. Finally, if the data type is constant, the modulation name is ended in B. If the data type is non-const nature, the modulation name is ended with A.