C/C ++ basics: function call conventions

Source: Internet
Author: User

C/C ++ function call conventions and function name modification rules

Programmers who use C/C ++ to develop software often encounter the following problems:
Problem, but when linking, it always reports that the function does not exist (Classic lnk
2001 error). Sometimes there are no errors in program compilation and linking, but a stack exception occurs when the function in the library is called. These phenomena usually occur when C and C ++ code are used together or
When a third-party library is used in a C ++ Program (not developed in C ++), this is actually a function call Convention (calling
Convention) and function name modification (decorated
Name. The function call method determines the order in which function parameters are written to the stack. The caller function or called function is responsible for clearing the parameters in the stack. The function name modification rules determine the compiler's

Which name modifier method is used to distinguish different functions? If the call conventions between functions do not match or the name modifier does not match, the above problems will occur. This article calls the functions of C and C ++ respectively.
The Conventions and function name modification rules are used to explain in detail, compare their similarities and differences, and illustrate the causes of the above problems.

Calling convention)

 
The function call convention not only determines the order of function parameters in the stack when a function is called, but also determines whether the caller function is used to clear the parameters in the stack and restore the stack. Function call conventions have many

In addition to common _ cdecl ,__ fastcall and _ stdcall, the C ++ compiler also supports the thiscall method. Many C/C ++ compilers also support
Naked
Call method. So many function call conventions are often confusing to many programmers. In the end, under what circumstances are they used? The following describes the call conventions of these functions.

1. _ cdecl

 
The command line parameter of the compiler is/GD. The _ cdecl method is the default function call convention of the C/C ++ compiler. All non-C ++ member functions and those that do not use _ stdcall or
The _ fastcall declared functions use the _ cdecl method by default. It uses the C function call method. function parameters are pushed to the stack in the order from right to left, the function caller is responsible for clearing the parameters in the stack,
Since each function call requires the compiler to generate code to clear (Restore) the stack, the program compiled using _ cdecl is much larger than the program compiled using _ stdcall,
_ Cdecl: The function caller is responsible for clearing function parameters in the stack. Therefore, this method supports variable parameters, such as printf and Windows APIs.
Wsprintf is the _ cdecl call method. For C functions, the naming convention in the __cdecl mode is to add an underline before the function name. For C ++ functions, unless otherwise specified
Use the extern "c" and C ++ functions to use different name modifiers.

2. _ fastcall

Command line parameters of the Compiler
Yes/GR. _ Fastcall function call Conventions use registers to pass parameters, usually the first two
DWORD parameters or smaller parameters are transmitted using ECx and EDX registers. Other parameters are imported to the stack in the order from right to left. The called function is responsible for clearing the parameters in the stack before returning them. Compiler usage
Two @ modifier function names, followed by the size of the function parameter list in decimal format, for example, @ function_name @ number. Note the _ fastcall function call.
There may be different implementations in different compilers, such as 16-bit compilers and 32-bit compilers. In addition, when using embedded assembly code, note that it cannot conflict with the registers used by the compiler.

3. _ stdcall

The command line parameter of the compiler is/GZ ,__ stdcall, which is the default caller of the PASCAL program.
Most windows APIs are also the _ stdcall call convention. _ Stdcall function call convention to stack function parameters from right to left, unless pointer or reference type parameters are used
All parameters are passed by passing values. The called function is responsible for clearing the parameters in the stack. For C functions, the _ stdcall name is modified by adding an underline before the function name, after the function name
Add @ and the size of function parameters, for example, _ functionname @ number

4. thiscall

Thiscall is only used for Calling C ++ member functions. function parameters are pushed to the stack from right to left. This pointer of a class instance is passed through the ECX register. Note that thiscall is not a keyword of C ++ and cannot be used to declare a function. It can only be used by the compiler.

5. Naked call

 
The compiler automatically adds the code for saving the ESI, EDI, EBX, and EBP registers to the function when necessary, and restores these registers when exiting the function.
The content of the tool. The function declared using the naked call method will not add such code, that is why it is called naked. Naked
Call is not a type modifier, so it must be used together with _ declspec.

By default, the compiling environment of VC uses the _ cdecl call convention.
Project setting... menu-C/C ++ = Code
Set the function call convention for the generation item. You can also add a separate confirmation letter, such as the keyword _ stdcall, _ cdecl, or _ fastcall, before the function declaration.
Number of calls. Winapi macros are commonly used for software development on Windows systems. It can be translated into appropriate function call conventions based on compilation settings. in Win32, it is defined
_ Stdcall.

Decorated name

Function Name Modification
(Decorated
Name) is a string created by the compiler during compilation. It is used to specify the definition or prototype of a function. Link programs or other tools sometimes need to specify the name of the function to locate the correct position of the function.

In most cases, programmers do not need to know the function name modification. The link program or other tools will automatically differentiate them. Of course, in some cases, you must specify the name of a function, for example, in a C ++ program,

To allow the link program or other tools to match the correct function name, you must specify the name decoration for the overload function and some special functions (such as constructors and destructor. Another type

The name is modified by calling C or C ++ functions in the assembler. If the function name or call conventions change the return value type or function parameter, the original name modification is no longer valid. You must specify a new
Name modification. The functions of C and C ++ use different name modifiers internally. The following describes the two methods respectively.

1. C compiler function name modification rules

 
For the _ stdcall call convention, the compiler and the linker will add an underline prefix before the output function name, and the "@" symbol after the function name and the number of bytes of its parameters, such
_ Functionname @ number. The _ cdecl call Convention only adds an underline prefix before the output function name, for example, _ functionname.
_ Fastcall: Add a "@" symbol before the output function name, followed by a "@" symbol and the number of bytes of its parameters. For example:
@ Functionname @ number.

2. function name modification rules of C ++ Compiler

C ++ function name repair
Decoration rules are complicated, but the information is more adequate. By analyzing and modifying the name, you can not only know the function call method, return value type, number of parameters, or even parameter type. No matter
_ Cdecl ,__ fastcall or _ stdcall call method. All function modifiers are "? "Start, followed by the name of the function, followed by the start ID and

The parameter table spelled out based on the parameter type code. For the _ stdcall method, the start identifier of the parameter table is "@ YG", and for the _ cdecl method is "@ ya".
The _ fastcall method is "@ Yi ". The spelling code of the parameter table is as follows:

X -- void

D -- char

E -- unsigned char

F -- short

H -- int

I -- unsigned int

J -- long

K -- unsigned long (DWORD)

M -- float

N -- double

_ N -- bool

U -- struct

....

 
The pointer method is special. Pa is used to represent the pointer and Pb is used to represent the const type pointer. The following code indicates the pointer type. If a pointer of the same type appears consecutively, replace it with "0 ".
"0"
Indicates a duplicate. The u table shows the structure type, which is usually followed by the type name of the struct. "@" is used to indicate the end Of the structure type name. The return value of a function is not specially processed. It is described in the same way as a function parameter, followed

The START sign of the parameter table. That is to say, the first item of the function parameter table actually represents the type of Return Value of the function. The end of the name is marked with "@ Z" after the parameter table. If this function does not have a parameter, the end is marked with "Z"
End of ID. The following two examples show the following function declaration:

Int function1 (char * var1, unsigned long );

Its function name is "? Function1 @ yghpadk @ Z ", but for function declaration:

Void function2 ();

The function modifier is "? Function2 @ ygxxz ".

 
For C ++ class member functions (whose call method is thiscall), the name modification of the function is slightly different from that of the non-member c ++ functions, first, insert "@" between the function name and the parameter table "@"
The class name guided by the character. The second is that the start ID of the parameter table is different. The public member function is identified by "@ Qae" to protect (protected) member functions.
Is "@ IAE", and the ID of the Private member function is "@ AAE". If the function declaration uses the const keyword, the corresponding IDs should be
For "@ QBE", "@ IBE", and "@ Abe ". If the parameter type is a reference of a class instance, use "aav1". For a reference of the const type, use "abv1 ".
The following uses ctest as an example to describe the naming rules for C ++ member functions:

Class ctest

{

......

PRIVATE:

Void function (INT );

Protected:

Void copyinfo (const ctest & SRC );

Public:

Long drawtext (HDC, long POs, const tchar * Text, rgbquad color, byte Bunder, bool bset );

Long insightclass (DWORD dwclass) const;

......

};

 
For a member function, its function name is "? Function @ ctest @ aaexh @ Z ", string" @ AAE "indicates this is a private function. Cheng
The member function copyinfo has only one parameter, which is a const reference parameter of the class ctest. Its function modifier name
Is "? Copyinfo @ ctest @ iaexabv1 @ Z ".
Drawtext is a complex function declaration. It includes not only string parameters, but also struct parameters and HDC handle parameters. It must be noted that HDC is actually a HDC _ structure type.

The parameter is "pauhdc __@", and its complete function modifier name
Is "? Drawtext @ ctest @ qaejpauhdc __@@ jpbdutagrg
Bquad @ e_n @ Z ". Insightclass is a common const function. Its member function ID is "@ QBE". The complete modifier is
Yes "? Insightclass @ ctest @ qbejk @ Z ".

Whether it is a C function name modifier or a C ++ function name modifier, The Case sensitivity of the characters in the output function name is not changed, which is different from the Pascal call convention, pascal agrees that the name of the function output is in uppercase without any modification.

3. view the function name Modification

 
There are two ways to check the name modification of the function in your program: Compile the output list or use the dumpbin tool. You can use the/FAC,/Fas, or/FACS command line parameters to compile
Output function or variable name list. Use dumpbin.exe
The/Symbols command can also obtain the list of function or variable names in the OBJ file or lib file. In addition, you can use undname.exe to convert the modifier name to an unmodified form.

Common problems caused by mismatch between function call conventions and name modification rules

If a stack exception occurs during function calling, it is caused by the mismatch of the function call conventions. For example, dynamic link library A has the following export functions:

Long makefun (long lfun );

 
The function call Convention used when a dynamic library is generated is _ stdcall. Therefore, the call convention for the function makefun in A. dll is compiled and generated.
It must be _ stdcall, that is, when the function is called, the parameter is pushed from right to left into the stack, and the function restores the stack itself when it returns. Now, a program module B needs to reference makefun IN A, which is used in the same way as.
C ++ compilation method, except that the function call method of Module B is _ cdecl. Because B contains the makefun function declaration in the header file provided by module A, makefun is added to Module B by others.

The function that calls makefun is considered to be the _ cdecl call method. The functions in Module B need to help restore the stack after makefun is called, but makefun is over.
When the stack is restored, the function in Module B causes a stack pointer error and stack exception. The macro phenomenon is that function calling is normal (because the parameter transmission order is the same
), Makefun has completed its own functions, but an error is thrown after the function is returned. The solution is also very simple, as long as the two modules set the same function call conventions during compilation.

 
After learning about the function call conventions and the function name modification rules, let's look at the lnk that often appears in libraries compiled in C ++.
The error 2001 is simple. Take the two modules in the preceding example as an example. during compilation, both modules adopt the _ stdcall call convention. However, A. dll uses the C language syntax to compile

Therefore, the name modification of makefun function in A. dll is "_ makefun @ 4 ". B contains the header file provided by.
Makefun function declaration, but because B uses C ++ language for compilation, makefun is named in Module B according to the name modification rules of C ++.
Is "? Makefun @ ygjj @ Z ", the compilation process is safe. When linking the program, the C ++ Linker will go to a. lib to find "? Makefun @ ygjj @ Z ",
A. Lib only contains "_ makefun @ 4", no "? Makefun @ ygjj @ Z ", the linker reports:

Error lnk2001: unresolved external symbol? Makefun @ ygjj @ Z

The solution is simple, that is, let Module B know that this function is compiled in C language, and extern "C" can do this. A library compiled in C language should consider that the program using this library may be a C ++ Program (using the C ++ compiler), so pay attention to this when designing header files. The header file should be declared as follows:

# Ifdef _ cplusplus

Extern "C "{

# Endif

Long makefun (long lfun );

# Ifdef _ cplusplus

}

# Endif

In this way, the C ++ compiler will know that the modified name of makefun is "_ makefun @ 4", and there will be no Link errors.

 
Many people don't understand why the "error" occurs when the compilers I use are Vc compilers.
Lnk2001 "error? In fact, the VC compiler will select the compilation method based on the source file extension. If the file extension is ". c", the compiler will compile it using the C syntax. If the extension is
". Cpp", the compiler will use the C ++ syntax to compile the program, so the best way is to use extern "C ".

========================================================== ======

It will be noted that compilers like GCC also adopt the _ cdecl method, so that for printf ("% d", I ++, I ++) and so on.

Another problem is the Variable Parameter Function of C language. It is estimated that this part is rarely involved in universities, but this is indeed a common feature of C language, such as printf.

The support for variable parameters mentioned above requires the function caller to clear function parameters in the stack. But why does this support variable parameters?

 
The parameter transfer involved in function calling is implemented through the stack. The sub-function reads the parameter passed to it from the stack, if the stack is pressed from left to right, the last parameter of the sub-function will be placed at the top of the stack, followed by inverted
The second parameter ......; if the stack is pressed from right to left, the first parameter of the sub-function is at the top of the stack, and then the second parameter is in turn ......, the sequence of stack pressure determines that the sub-function reads
Parameter location. For a function with variable parameters, it does not know several parameters and requires some information. For printf, it is analyzed from the formatted string FMT,
There are several parameters in total. Therefore, the method of clearing the stack returned by the called function cannot be implemented for variable parameters, because the called function does not know the number of parameters to be popped up. When a function is called, it is passed to the called function by itself.
The number of parameters (by compressing the parameter stack) is clear, in this way, the stack cleanup after the returned result of the called function can be accurate (no more or no less parameter cleanup ).

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.