Dll details and macd indicators details
[To] http://www.cnblogs.com/xuemaxiongfeng/articles/2461632.html
I don't know why to use the WINAPI macro definition. I found the following definition after checking it. The difference is needed.
Differences 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
1.Almost every windows api function we write is of the _ stdcall type. First, we need to know the difference between the two: STACK (STACK, A storage structure ). After the function call is complete, the stack needs to be cleared. Here is the key to the problem. How can we clear it ?? If our function uses _ cdecl, the stack clearing is done by the caller. In terms of COM, it is done by the customer. This brings about a difficult problem. Different compilers may generate stacks in different ways. Can the caller complete the cleanup work normally? The answer is no. If _ stdcall is used, the above problem is solved, and the function solves the clearing work by itself. Therefore, in cross-platform (Development) calls, we use _ stdcall (although sometimes it appears as WINAPI ). So why do we still need _ cdecl? When the parameters of such a function, such as fprintf (), are variable and variable, the caller cannot know the length of the parameter in advance, and the cleanup operation afterwards cannot proceed normally, therefore, we can only use _ cdecl in this case. Here we have a conclusion that 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. the main difference is parameter passing and stack play. generally, c ++ uses _ cdecl and windows uses _ stdcall (API ).
_ Cdecl is the call Convention used by C/C ++ and MFC programs by default. You can also add the _ cdecl keyword when declaring a function. When _ cdecl is used, function parameters are pushed to the stack in the order from right to left, and the caller pops up the parameter stack to clear the stack. Therefore, a function that implements variable parameters can only use this call convention. Every function using the _ cdecl Convention must contain the code for clearing the stack, so the size of the executable file generated will be relatively large. _ Cdecl can be written as _ cdecl.
_ Stdcall is used to call Win32 API functions. When _ stdcall is used, function parameters are written to the stack in the order from right to left. The called function clears the stack of the transfer parameter before returning the function. The number of function parameters is fixed. Because the function body knows the number of passed parameters, the called function can directly clear the stack of the passed parameters with a ret n command before returning the result. _ Stdcall can be written as _ stdcall.
_ Fastcall conventions are used in scenarios with high performance requirements. _ Fastcall: The two DWORD parameters starting from the left of the function are placed in the ECX and EDX registers respectively, the other parameters are still transmitted from the right to the left pressure stack. The called function clears the stack of the transfer parameter before returning. _ Fastcall can be written as _ fastcall
3._ Stdcall:
_ Stdcall 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 ).
_ Stdcall is the default calling method of the Pascal program. It is usually used in Win32 Api. The function uses the stack pressure method from right to left and clears the stack when it exits. After compiling a function, VC adds an underline prefix to the function name, and adds "@" and the number of bytes of the parameter to the function name.
_ Cdecl:
_ Cdecl c indicates that the parameters are pushed to the stack in sequence from right to left. The caller pushes the parameters to the stack. 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.
_ Cdecl is the default call Method for C and C ++ programs. Every function that calls it contains the code to clear the stack. Therefore, the size of the executable file generated is larger than that of the call to the _ stdcall function. The function uses the stack pressure mode from right to left. After compiling a function, VC adds an underline prefix to the function name. Is the default MFC call convention.
_ Fastcall:
_ 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 DWORD or smaller parameters, and the remaining parameters are still transmitted from the right to the left pressure stack, 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.
_ Fastcall functions use registers to pass parameters. After compiling a function, VC adds the "@" prefix to the function name, and adds "@" and the number of parameters after the function name.
Thiscall:
Thiscall is only applicable to "C ++" member functions. This pointer is stored in the CX register and the parameter is pressed from right to left. Thiscall is not a keyword and cannot be specified by programmers.
Naked call:
1-4 call timing. If necessary, when entering the function, the compiler will generate code to save the ESI, EDI, EBX, and EBP registers, when you exit the function, the code is generated to restore the content of these registers.
Naked call does not generate such code. The naked call is not a type modifier, so it must be used together with _ declspec.
Note:Most APIs use the _ stdcall call specification, because almost all languages Support _ stdcall calls. in contrast, __cdecl can only be used in C language. however, _ cdecl calls have a feature that can implement Variable Parameter Function calls, such as printf, which is impossible to call with _ stdcall.
_ Fastcall is rare, but Borland C ++ Builder often uses this call method.
If you need to share the Code, such as writing a DLL, the recommended method is to use _ stdcall for calling, because this applies to the widest range. if the code written in C ++ is called by a language such as Delphi, it must be declared as _ stdcall, because Pascal does not support cdecl calling (maybe the latest version of Delphi can support it, I don't know ). in other places, for example, writing COM components, almost all use stdcall calls. in VC, Delphi, or C ++ Builder, you can change the default function call specification from the Project Settings. Of course, you can also add _ stdcall ,__ cdecl when declaring a function, __fastcall keyword to clearly indicate which call specifications are used for this function.
4._ Declspec:
_ Declspec is mainly used to describe the DLL extraction function. In some cases, it is easier to use _ declspec (dllexport) to extract the function from the DLL, which is more convenient than to use a traditional DEF file. you can also use _ declspec (dllimport) in a common program to indicate that the function is an export function located in another DLL.
Appendix:
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.
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 function into an appropriate call convention. In WIN32, it is defined as _ stdcall. You can use the WINAPI macro to create your own APIs.
Name modification conventions
1,Decoration name)
The "C" or "C ++" functions are identified by modifier internally (Compilation and link. Modifier is a string generated by the compiler when compiling a function definition or prototype. In some cases, modifying the name of a function is necessary, for example, specifying the output "C ++" overload function, constructor, and destructor in the module definition file, for example, call the "C" or "C ++" function in the assembly code.
Modifier names are jointly determined by function names, class names, call conventions, return types, parameters, and so on.
2,The name modification conventions vary with the call conventions and compilation types (C or C ++. The function name modification conventions vary with the compilation type and call conventions.
A,Rules for modifying function names during C Compilation:
The _ stdcall call Convention adds an underline prefix before the output function name, followed by the "@" symbol and the number of bytes of the parameter. The format is _ 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 case sensitivity of the output function name. This is different from PASCAL's call conventions. PASCAL's output function names are not modified and all are capitalized.
B,Rules for modifying function names during C ++ Compilation:
_ Stdcall call conventions:
1),Take "?" Start of the function name, followed by the function name;
2),The function name starts with "@ YG" to identify the parameter table, 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 a pointer of the same type appears consecutively, 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, and the pointer mark is before the data type referred to by the parameter table;
5,The end of the name is marked with "@ Z" after the parameter table. If this function does not have a 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:
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 ".
The "_ cedcl" Statement for saving functions by VC ++ will only be called by C/C ++.
CB uses four modifiers for output function declaration.
// _ Cdecl
The default value of cb. It will add _ before the output function name and keep this function name unchanged. parameters are passed to the stack in sequence from right to left, it can also be written as _ cdecl and cdecl.
// _ Fastcall
The parameters of the function modified by her will be processed by registers with the intention of adding @ before the function name, and the parameters will be pushed to the stack in the order from left to right;
// _ Pascal
It indicates that the function name uses the naming convention in Pascal format. In this case, all function names are capitalized. The parameters are pressed from left to right;
// _ Stdcall
Use the standard function name. The function name will not change. When _ stdcall is used. The parameter can be set to _ stdcall in the order from right to left;
The "_ cedcl" Declaration for the function can only be called by C/C ++.
Note:
1,_ Beginthread requires the thread function address of _ cdecl and the thread function address of _ stdcall required by _ beginthreadex and CreateThread.
2,Generally, all WIN32 functions are _ stdcall. Windef. h has 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 modifier is written in the above Order.
The function of extern "C": If Add (int a, int B) is compiled in the c language compiler and used in the c ++ file, it must be declared in the C ++ file: extern "C" Add (int a, int B ), because the c compiler and c ++ compiler have different interpretations of function names (function parameters must be considered when the c ++ compiler interprets a function name, which facilitates function overloading, in C language, there is no function overload problem). The essence of using extern "c" is to tell the c ++ compiler that this function is a function in the C library. If you do not use extern "C", a link error occurs.
It is 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
4.MFC provides some macros. You can use AFX_EXT_CLASS to replace _ declspec (DLLexport) and modify the class name to export the class, AFX_API_EXPORT to modify the function, and 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 and Termination. Whenever a new process or a new thread of the Process accesses the DLL, or when every process or thread accessing the DLL no longer uses the DLL or ends, it will call DLLMain. However, using TerminateProcess or TerminateThread to end a process or thread does not call DLLMain.
7,A dll has only one instance in the memory.
The relationship between the DLL program and the program that calls its output function:
1),The relationship between DLL and process and thread
The DLL module is mapped to the virtual address space of the process that calls it.
The DLL Memory is allocated from the virtual address space of the calling process and can only be accessed by the thread of the process.
The DLL handle can be used by the calling process, and the call Process Handle can be used by the DLL.
DLL can have its own data segment but does not have its own stack. It uses the stack of the calling process, which is the same as the stack mode of the application that calls it.
2),About shared data segments
The global variables defined by DLL can be accessed by the calling process; The DLL can access the global data of the calling process. Each process using the same DLL has its own DLL global variable instance. If multiple threads concurrently access the same variable, 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, the Local Thread storage should be used (TLS, Thread Local Strorage ).