First of all, these three modifiers are c and c++ calling conventions.

The Calling convention determines the following: the stacking order of function arguments, whether the caller or the callee pops the arguments off the stack, and the method that produces the function modifier name . MFC supports the following calling conventions:     

__cdecl, __stdcal and __fastcalll are function call specifications, which specify the order and method of parameter entry and exit. If you only use VC programming , you don’t need to care, but you should pay attention when communicating with other languages ​​such as C++ and Pascal. In the same way, the call can be successful. In addition, functions that accept variable arguments like printf can only be implemented with cdecl .   

_cdecl

The parameters are pushed onto the stack in right-to-left order, and the caller pops the parameters off the stack. For “C” functions or variables, the modifier name is underlined before the function name. For the “C++” function, it is different.

For example, the modified name of the function void test (void) is _test; for the “C++” global function that does not belong to a class, the modified name is ?test@@ZAXXZ.

This is the MFC default calling convention. Since the caller is responsible for popping the parameters off the stack, you can define a variable number of parameters for the function, such as the printf function.

_stdcall

The parameters are pushed onto the stack in right-to-left order, and the callee pops the parameters off the stack. For a “C” function or variable, the modifier name is prefixed with an underscore, followed by the function name, followed by the symbol “@” and the number of bytes of the argument, such as the function name int func(int a, double b) is _func @12. For the “C++” function, it is different.

All Win32 API functions follow this convention.

_ fastcall  

The first three parameters of the function parameter list are put into the registers eax, edx, ecx, and other parameters are pushed onto the stack. Fastcall is used by BCB to better compatible with the VCL written by Delphi. The default call in Delphi is fastcall, which puts the first three parameters of the function parameter list into the register.

For example, in fact, when adding a keyword to a function declaration, for example, many API functions are declared like this: 
int WINAPI MessageBoxA (HWND, LPCSTR, LPSTR, UINT); 
and WINAPI is actually __stdcall.
Most APIs use the __stdcall call specification, because almost all languages support __stdcall calls. In contrast, __cdecl can only be used in C. But the __cdecl call has a feature that enablesvariable Function calls to parameters, such as printf, are not possible with __stdcall calls. 
__fastcall is a rare call specification, but it is used more often in Borland C++ Builder.
If there is a need to share code , such as writing a DLL, the recommended method is to use __stdcall to call, because this is the most widely used. If the code written in C++ is called for a language such as Delphi, it must be declared as __stdcall, because Pascal does not Support for cdecl calls (perhaps the latest version of Delphi can support it, maybe I don’t know). In other places, such as writing COM components, almost all use stdcall calls. In VC or Delphi or C++Builder You can change the default function call specification from the project settings. Of course, you can also add __stdcall, __cdecl, __fastcall keywords to indicate which call specification the function uses.  

__declspec is mainly used to explain the DLL’s export function. In some cases, __declspec(dllexport) is used to derive functions in DLL, which is more convenient than using traditional DEF files.

The program can also use __declspec(dllimport) to indicate that the function is an exported function located in another DLL.

 

Cdecl Clears the stack by the caller 
  stdcall Clears the stack by the called   function   
  fastcall is to put the first three parameters of the function parameter list into the registers eax, edx, ecx, other parameters pushed.

1.

When I wrote the thread function today, I found that there is a requirement for the definition of ThreadProc in msdn: DWORD WINAPI ThreadProc(LPVOID lpParameter);

I don’t understand why I use the WINAPI macro definition. After checking it, I found the following definition. So you need to distinguish between __stdcall and __cdecl; #define CALLBACK __stdcall 
#define WINAPI __stdcall 
#define WINAPIV __cdecl 
#define APIENTRY WINAPI 
#define APIPRIVATE __stdcall 
#define PASCAL __stdcall 
#define cdecl _cdecl 
#ifndef CDECL 
#define CDECL _cdecl 
# Endif

Almost every WINDOWS API function we write is __stdcall type. First, we need to understand the difference between the two: WINDOWS function call requires stack (STACK, a first-in and first-out storage structure). When the function call is completed, the stack needs to be clear. Here is the key to the problem. How to clear it? ? If our function uses _cdecl, then the cleanup of the stack is done by the caller in the COM terminology. This brings up a thorny problem. Different compilers generate stacks in different ways. Can the caller finish the cleanup normally? The answer is no. If __stdcall is used, the above problem is solved, and the function solves the cleanup work by itself. So, in the call to the (development) platform, we all use __stdcall (although sometimes it looks like WINAPI). So why do you need _cdecl? When we encounter such a function such as fprintf () its parameters are variable, not long, the caller can not know the length of the parameter beforehand, the post-cleaning work can not be carried out normally, therefore, we only Can use _cdecl. Here we have a conclusion, if your program does not involve variable parameters, it is best to use the __stdcall keyword.

2.

__cdecl, __stdcall is the declared function call protocol. It is mainly the difference between the parameter and the bullet stack. Generally c++ uses __cdecl, most of the windows use __stdcall(API)

__cdecl is the default calling convention used by C/C++ and MFC programs. It can also be specified manually by adding the __cdecl keyword to the function declaration. With the __cdecl convention, function arguments are pushed onto the stack in right-to-left order, and the calling function pops the arguments off the stack to clean up the stack. Therefore, functions that implement mutable arguments can only use this calling convention. Since every function that uses the __cdecl convention contains code to clean up the stack, the resulting executable will be larger. __cdecl can be written as _cdecl. 
The __stdcall calling convention is used to call Win32 API functions. When the __stdcall convention is used, the function parameters are pushed onto the stack in right-to-left order. The called function cleans the stack of the transfer parameters before returning, and the number of function parameters is fixed. Since the function body itself knows the number of arguments passed in, the called function can directly clean up the stack of passed arguments with a ret n directive before returning. __stdcall can be written as _stdcall. 
The __fastcall convention is used for situations where performance is very high. The __fastcall convention puts two parameters of the function from the left that are no larger than 4 bytes (DWORD) in the ECX and EDX registers, and the remaining parameters are still pushed from the right to the left. The called function is returned before returning. Clean up the stack of transfer parameters. __fastcall can be written as _fastcall

3.

__stdcall:

The _stdcall calling convention is equivalent to the PASCAL calling convention that is often used in 16-bit dynamic libraries.

 

The PASCAL calling convention is no longer supported in 32-bit VC++ 5.0 (actually it has been defined as __stdcall. __fortran and __syscall are not supported except for __pascal), instead the __stdcall calling convention. The two are essentially the same, that is, the parameters of the function are passed from the right to the left through the stack, and the called function cleans up the memory stack of the transfer parameters before returning, but the difference is the modified part of the function name (the modified part of the function name) This will be explained in detail later).

_stdcall is the default calling method of Pascal program. It is usually used in Win32 Api. The function adopts the stacking method from right to left, and it clears the stack when it exits. After VC compiles the function, it will prefix the function name with an underscore prefix, and add “@” and the number of bytes of the parameter after the function name.

_cdecl:

The _cdecl c calling convention pushes the parameters onto the stack in right-to-left order, and the caller pops the parameters off the stack. The memory stack for passing parameters is maintained by the caller (because of this, functions that implement mutable arguments can only use this calling convention). In addition, there are differences in the definition of function name modifications.

_cdecl is the default way to call C and C++ programs. Every function that calls it contains code that empties the stack, so the resulting executable size will be larger than the _stdcall function. The function uses a right-to-left push stack. After VC compiles the function, it will prefix the function name with an underscore. Is the MFC default calling convention.

__fastcall:

The __fastcall calling 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 transfer the first two double words (DWORD) or smaller parameters, The remaining parameters are still pushed from right to left, and the called function cleans up the memory stack of the transfer parameters before returning. It differs from the first two in terms of function name modification conventions.

The function of _fastcall method uses the register to pass parameters. After VC compiles the function, it will prefix the function name with “@”, and add “@” and the number of bytes of the parameter after the function name.

Thiscall:

Thiscall is only applied to “C++” member functions. The this pointer is stored in the CX register and the parameters are pressed from right to left. Thiscall is not a keyword and therefore cannot be specified by the programmer.

Naked call:

When using the calling convention of 1-4, if necessary, the compiler will generate code to save the ESI, EDI, EBX, EBP registers when entering the function, and generate code to restore the contents of these registers when the function exits.

Naked call does not produce such code. Naked call is not a type modifier and must be used with _declspec.

Attached:

The keywords __stdcall, __cdecl, and __fastcall can be added directly before the function to be output, or in the setting…\C/C++\Code Generation item in the compilation environment. When the keyword added before the output function is different from the choice in the compilation environment, the keyword directly added before the output function is valid. Their corresponding command line parameters are /Gz, /Gd, and /Gr. The default state is /Gd, which is __cdecl.

To fully mimic the PASCAL calling convention, you must first use the __stdcall calling convention. As for the function name modification convention, you can simulate it by other methods. Another thing worth mentioning is the WINAPI macro. Windows.h supports this macro, which translates the function into the appropriate calling convention. In WIN32, it is defined as __stdcall. Use the WINAPI macro to create your own APIs.

Name modification convention

1. Decoration name The 
“C” or “C++” function is internally identified (compiled and linked) by the modifier name. A modifier name is a string that the compiler generates when compiling a function definition or prototype. In some cases it is necessary to use the modified name of the function, such as specifying the output “C++” overloaded function, constructor, destructor in the module definition file, and calling “C” or “C++” function in assembly code. Wait.

The modifier name is determined by the function name, class name, calling convention, return type, and parameters.

2. The name modification convention varies with the calling convention and the type of compilation (C or C++). Function name modification conventions vary with the type of compilation and the calling convention, as explained below.

a, C compile time function name modification convention rules:

The __stdcall calling convention adds an underscore prefix to the output function name followed by an “@” symbol and the number of bytes of its argument, in the format _functionname@number.

The __cdecl calling convention only prefixes the output function name with an underscore prefix in the format _functionname.

The __fastcall calling convention adds an “@” sign before the output function name, followed by an “@” symbol and the number of bytes of its argument, in the format @functionname@number.

They do not change the character case in the output function name. This is different from the PASCAL calling convention. The function name output by the PASCAL convention has no modification and is all uppercase.

b, C++ compile time function name modification convention rules:

__stdcall calling convention: 
1, with “?” to identify the beginning of the function name, followed by the function name; 
2, the function name is followed by “@@YG” to identify the beginning of the parameter table, followed by the parameter table; 
3, the parameter table is represented by a 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– denotes the pointer, the following code indicates the pointer type. If the pointer of the same type appears continuously, it is replaced by “0”, and a “0” represents a repetition; 
4. Parameter list The first item is the return value type of the function, followed by the data type of the parameter, and the pointer is identified before the data type it refers to; 
5. After the parameter table, the end of the entire name is identified by “@Z”, if the function If there is no parameter, it ends with the “Z” mark.

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 calling convention: The 
rule is the same as the above _stdcall calling convention, except that the starting identifier of the parameter table is changed from “@@YG” to “@@YA” above.

__fastcall calling convention: The 
rule is the same as the above _stdcall calling convention, except that the starting identifier of the parameter table is changed from “@@YG” to “@@YI” above. 
VC++’s default statement for functions is “__cedcl”, which will only be called by C/C++.

CB uses the default value of the four modifiers 
//__cdecl 
cb in the output function declaration . It adds _ before the output function name, and keeps the function name unchanged. The parameters are passed to the stack in order from right to left. Can be written in the form of _cdecl and cdecl. 
//__fastcall 
The parameters of the function she modified will use the register to handle it. The function name is preceded by @, and the parameters are pushed in order from left to right. 
//__pascal 
describes the function name using Pascal format. Convention. At this time, the function name is all uppercase. Parameters are pushed in order from left to right; 
//__stdcall 
uses the standard agreed function name. The function name does not change. When using __stdcall modifier. Parameters are pushed in order from right to left, or they can be _stdcall;

VC++’s default statement for functions is “__cedcl”, which will only be called by C/C++.

 

 

note:

1, _beginthread requires __cdecl thread function address, _beginthreadex and CreateThread require __stdcall thread function address.

2, the general WIN32 function is __stdcall. And in Windef.h there are the following definitions:

 #define CALLBACK __stdcall

 #define WINAPI __stdcall

3, extern “C” _declspec (dllexport) int __cdecl Add (int a, int b);

   Typedef int (__cdecl*FunPointer)(int a, int b);

   The modifiers are written in the above order.

4, the role of extern “C”: If Add (int a, int b) is compiled in the c compiler, but used in c + + files, you need to declare in the c + + file: extern “C” Add (int a, int b), because the c compiler and the c++ compiler have different interpretations of function names (c++ compilers should consider function arguments when interpreting function names, which is convenient for function overloading, and there is no function overloading in c language The problem), using extern “C”, is essentially telling the C++ compiler, which is a function in the c library. If you do not use extern “C”, a link error will occur.

Generally used as follows:

#ifdef _cplusplus

#define EXTERN_C extern “C”

#else

#define EXTERN_C extern

#endif

#ifdef _cplusplus

Extern “C”{

#endif

 EXTERN_C int func(int a, int b);

#ifdef _cplusplus

}

#endif

5, MFC provides some macros, you can use AFX_EXT_CLASS instead of __declspec (DLLexport), and modify the class name to derive the class, AFX_API_EXPORT to modify the function, AFX_DATA_EXPORT to modify the variable

AFX_CLASS_IMPORT: __declspec(DLLexport)

AFX_API_IMPORT: __declspec(DLLexport)

AFX_DATA_IMPORT: __declspec(DLLexport)

AFX_CLASS_EXPORT: __declspec(DLLexport)

AFX_API_EXPORT: __declspec(DLLexport)

AFX_DATA_EXPORT: __declspec(DLLexport)

AFX_EXT_CLASS: #ifdef _AFXEXT

   AFX_CLASS_EXPORT

        #else

   AFX_CLASS_IMPORT

6, DLLMain is responsible for initialization (initialization) and termination (Termination) work, whenever a new process or a new thread of the process access DLL, or each process or thread accessing the DLL no longer use DLL or end, will Call DLLMain. However, ending the process or thread with TerminateProcess or TerminateThread does not call DLLMain.

7, a DLL has only one instance in memory

The relationship between the DLL program and the program that calls its output function:

1), the relationship between DLL and process, thread

The DLL module is mapped to the virtual address space of the process that called it.

The memory used by the DLL is allocated from the virtual address space of the calling process and can only be accessed by the thread of the process.

The handle of the DLL can be used by the calling process; the handle of the calling process can be used by the DLL.

A DLLDLL can have its own data segment, but without its own stack, use the stack of the calling process, the same stack mode as the application that called it.

2) About the shared data segment

The global variables defined by the DLL can be accessed by the calling process; the DLL can access the global data of the calling process. Every process that uses the same DLL has its own instance of a DLL global variable. If multiple threads access the same variable concurrently, you need to use the synchronization mechanism; for a DLL variable, if you want each thread that uses the DLL to have its own value, you should use Thread Local Strorage.

Almost every WINDOWS API function we write is __stdcall type. First, we need to understand the difference between the two: WINDOWS function call requires stack (STACK, a first-in and first-out storage structure). When the function call is completed, the stack needs to be cleared. Here is the key to the problem. How to clear it? ? If our function uses _cdecl, then the cleanup of the stack is done by the caller in the COM terminology. This brings up a thorny problem. Different compilers generate stacks in different ways. Can the caller finish the cleanup normally? The answer is no. If __stdcall is used, the above problem is solved, and the function solves the cleanup work by itself. So, in the call to the (development) platform, we all use __stdcall (although sometimes it looks like WINAPI). So why do you need _cdecl? When we encounter such a function such as fprintf () its parameters are variable, not long, the caller can not know the length of the parameter beforehand, the post-cleaning work can not be carried out normally, therefore, we only Can use _cdecl. Here we have a conclusion, if your program does not involve variable parameters, it is best to use the __stdcall keyword. 

Another: 
_cdecl 
pushes the parameters onto the stack in right-to-left order, and the caller pops the parameters off the stack. For “C” functions or variables, the modifier name is underlined before the function name. For the “C++” function, it is different. 
For example, the modification name of the function void test(void) is _test; for the “C++” global function that does not belong to a class, the modification name is ?test@@ZAXXZ . 
This is the MFC default calling convention. Since the caller is responsible for popping the parameters off the stack, you can define a variable number of parameters for the function, such as the printf function.

Stdcall, like pascal, is a pascal calling convention 
that pushes parameters into the stack in right-to-left order, and the callee pops the parameters off the stack. For a “C” function or variable, the modifier name is prefixed with an underscore, followed by the function name, followed by the symbol “@” and the number of bytes of the argument, such as the function int func(int a, double b) whose name is _func@ 12 . For the “C++” function, it is different.