_stdcall, _cdecl,__fastcall in-depth analysis

Source: Internet
Author: User
Tags types of functions

As a relatively independent function, they work together to complete the entire software system. There may be some modules that are more versatile and will still be used when constructing other software systems. In the construction of software systems, if the source code of all the modules are statically compiled into the entire application EXE file, there are some problems: one drawback is to increase the size of the application, it will occupy more disk space, the program will also consume a large amount of memory space, resulting in the waste of system resources, another disadvantage is that When writing large EXE programs, each time you modify the rebuild, you must adjust the compilation of all the source code, increase the complexity of the compilation process, and not conducive to periodic unit testing.

A completely different, more efficient programming and operating environment is available on the Windows system platform, where you can create separate program modules as smaller DLLs (Dynamic linkable Library) files and compile and test them separately. At run time, only if the EXE program actually calls these DLL modules will the system load them into memory space. This approach not only reduces the size of the EXE file and the need for memory space, but also enables these DLL modules to be used by multiple applications at the same time. Windows itself implements some of the main system functions in the form of DLL modules.

In general, a DLL is a disk file with a. dll,. DRV,. FON,. SYS and many with. EXE is an extension of the system file can be a DLL. It consists of global data, service functions, and resources, which are loaded into the virtual space of the calling process at runtime and become part of the calling process. If there is no conflict with other DLLs, the file is typically mapped to the same address on the process virtual space. DLL modules contain various export functions that are used to provide services to the outside world. A DLL can have its own data segment, but it has no stack of its own, using the same stack pattern as the application that invokes it; a DLL has only one instance in memory; The DLL implements the code encapsulation, and the DLL is independent of the specific programming language and compiler.

In the WIN32 environment, each process replicates its own read/write global variables. If you want to share memory with other processes, you must use a memory-mapped file or declare a shared data segment. The stack memory required by the DLL module is allocated from the stack of the running process. Windows matches the process function call to the exported function of the DLL file when the DLL module is loaded. The operation of the Windows operating system on a DLL is simply to map the DLL to the virtual address space of the process that needs it. Any object (including variables) created by code in a DLL function is owned by the thread or process that called it.

Invocation mode
1, static call Mode: By the compilation system to load the DLL and the application at the end of the DLL unload encoding (if there are other programs using the DLL, Windows to the DLL application record minus 1, until all the relevant program to end the use of the DLL to release it, simple and practical, but not flexible, Can only meet the general requirements.

Implicit invocation: The generation of dynamic connection libraries is required. LIB file is added to the application's project, and you want to use the functions in the DLL, you only need to explain. Implicit calls do not require calls to LoadLibrary () and FreeLibrary (). When a programmer builds a DLL file, the linker automatically generates a corresponding LIB import file. The file contains the symbol name and optional identification number of each DLL export function, but does not contain the actual code. The LIB file is compiled into the application project as an alternative to the DLL.

When a programmer compiles a build application by statically linking it, the calling function in the application matches the exported symbol in the LIB file, and these symbols or identifiers enter into the generated EXE file. LIB file also contains the corresponding DL L file name (but not the full pathname), the linker stores it inside the EXE file.

When a DLL file needs to be loaded while the application is running, Windows discovers and loads the DLL based on that information, and then implements a dynamic link to the DLL function through the symbol name or identification number. All DLL files that are called by the application are loaded into memory when the application EXE file is loaded. An executable link to an input library file that contains information about the DLL's output functions (. LIB file). The operating system loads the DLL when it loads using an executable program. The executable program calls the DLL's output function directly through the function name, and the calling method is the same as the other functions inside the program.

2, Dynamic Call mode: is by the programmer with the API function to load and unload the DLL to achieve the purpose of calling the DLL, the use of more complex, but more efficient use of memory, is the important way to prepare large applications.

Explicit invocation: Refers to the application of LoadLibrary or MFC provided by the AfxLoadLibrary explicitly do their own dynamic connection library redeployment, the dynamic Connection library filename is the above two function parameters, and then with the GetProcAddress () Gets the function that you want to introduce. From there, you can invoke this ingest function just as you would with a custom function in this application. You should release the dynamic Connection library with the AfxFreeLibrary provided by FreeLibrary or MFC before the application exits. Call Win32 's loadlibary function directly and specify the path of the DLL as the parameter. Loadlibary returns the HINSTANCE parameter, which is used by the application when calling the GetProcAddress function. The GetProcAddress function converts a symbol name or identification number to an address inside a DLL. The programmer can determine when the DLL file is loaded or not loaded, and the explicit link determines which DLL file to load at run time. A program that uses a DLL must load (LoadLibrary) load the DLL before it is used to get a handle to a DLL module, and then call the GetProcAddress function to get a pointer to the output function, which must unload the DLL (FreeLibrary) before exiting.

Windows will follow the following search order to locate the DLL:

The directory containing the EXE file
Current working directory of the process
Windows system directory
Windows directory
A list of directories listed in the PATH environment variable
DLLs in MFC

NON-MFC DLL: Refers to the use of MFC class library structure, directly written in C language DLL, its output function is generally used in the standard C interface, and can be written by non-MFC or MFC applications.
Regular DLLs: Like the following Extension DLLs, are written in the MFC class library. The obvious feature is that there is a class in the source file that inherits the CWINAPP. It can also be subdivided into statically connected to MFC and dynamically connected to MFC.
Dynamic connection libraries that are statically connected to MFC are supported only by the Pro and Enterprise editions of VCs. The output functions inside the DLL application can be used by any WIN32 program, including applications that use MFC. The input function has the following form:

extern "C" EXPORT yourexportedfunction ();

Without the extern "C" modifier, the output function can only be called from C + + code.

DLL applications derive from CWINAPP, but do not have a message loop.

The output function inside a regular DLL application that is dynamically linked to MFC can be used by any WIN32 program, including applications that use MFC. However, all functions that are output from the DLL should start with the following statement:

Afx_manage_state (AfxGetStaticModuleState ())
This statement is used to correctly toggle the state of the MFC module.

The Regular DLL can be called by applications written by all languages that support DLL technology. In this dynamic connection library, it must have a class inherited from CWinApp, the DLLMain function is provided by MFC, do not have to write their own explicit.

Extension DLL: Used to implement the reuse of classes inherited from MFC, that is to say, with this type of dynamic connection library, can be used to output a class inherited from MFC. Its output functions can only be used by applications that use MFC and are dynamically linked to MFC. You can inherit from MFC what you want, a more appropriate class for your own use, and provide it to your application. You are also free to give your application an object pointer to an MFC or MFC inheriting class. The Extension DLL is created using the dynamic Connection version of MFC, and it is only called by applications written with the MFC class library. Unlike Extension DLLs and Regular DLLs, it does not have an object of classes inherited from CWINAPP, so you must add initialization code and end code for your DLLMain function.

Compared to regular DLLs, there are the following differences:

1. It has no object derived from CWinApp;

2, it must have a DLLMain function;

3, DLLMain call AfxInitExtensionModule function, must check the return value of the function, if return 0,dllmmain also return 0;

4. If it wants to output an object or resource of type CRuntimeClass, you need to provide an initialization function to create a CDynLinkLibrary object. Also, it is necessary to output the initialization function;

5. An MFC application that uses an extension DLL must have a class derived from CWinApp, and the initialization function of the extension DLL is typically called in InitInstance.

DLL Entry function

1, each DLL must have an entry point, DLLMain is a default entry function. DLLMain is responsible for initializing and ending the work, calling DLLMain whenever a new process or a new thread of the process accesses the DLL, or every process that accesses the DLL or the thread no longer uses the DLL or ends. However, using terminateprocess or TerminateThread to end a process or thread does not call DLLMain.

Function prototypes for DllMain:

BOOL apientry DLLMain (HANDLE hmodule,dword ul_reason_for_call,lpvoid
lpreserved)
{
Switch (Ul_reason_for_call)
{
Case Dll_process_attach:
.......
Case Dll_thread_attach:
.......
Case Dll_thread_detach:
.......
Case Dll_process_detach:
.......
return TRUE;
}
}

Parameters:

Hmoudle: A handle that is passed to a dynamic library when it is called (in fact, it is a selector pointing to the _dgroup segment);

Ul_reason_for_call: is a flag that explains why a dynamic library is being tuned. When a process or thread loads or unloads a dynamic connection library, the operating system invokes the entry function and explains why the dynamic connection library was called. All of its possible values are:

Dll_process_attach: process is called;

Dll_thread_attach: thread is called;

Dll_process_detach: Process is stopped;

Dll_thread_detach: Thread is stopped;

Lpreserved: is a parameter reserved by the system;

2, _DllMainCRTStartup

In order to use the DLL version of the "C" Runtime (Crt,c run Time library), a DLL application must specify _DllMainCRTStartup as the entry function, and the DLL's initialization function must be DLLMain.

_DllMainCRTStartup completes the following tasks: When a process or thread bundle (Attach) to a DLL allocates space and initialization for the "C" Runtime data (c runtime data) and constructs a global "C + +" object when the process or thread terminates using the DLL (Det ACH), clean the C runtime Data and destroy the global "C + +" object. It also calls the DLLMain and RawDllMain functions.

RawDllMain is required when a DLL application is dynamically linked to an MFC DLL, but it is statically linked to the DLL application. Explains why state management is being described.

About calling conventions

There are two conventions for dynamic library output functions: The calling convention and the name Decoration Convention.

1) calling convention (calling convention): determines the order in which the function parameters are passed in and out of the stack, which is called by the caller or by the caller, and the modifier conventions used by the compiler to identify the function name.

There are a number of function calling conventions, here is a brief:

1. The __stdcall calling convention is equivalent to the PASCAL calling convention commonly used in 16-bit dynamic libraries. In a 32-bit vc++5.0, the Pascal calling convention is no longer supported (in fact it has been defined as __stdcall. In addition to __pascal, __fortran and __syscall are not supported), instead the __stdcall calling convention. The two are essentially consistent, that is, the function's arguments are passed from right to left through the stack, and the called function cleans up the memory stack of the transfer parameters before returning, but differs from the decorated part of the function name (which is explained in detail later in the section on the function name).

_stdcall is the default invocation of the Pascal program, and is typically used in the Win32 API, where the function uses a right-to-left stack and empties itself on exit. After the VC compiles the function, it adds an underscore prefix to the function name, followed by the function name with the "@" and the number of bytes of the parameter.

2, C calling convention (that is, with __cdecl keyword description) in the right-to-left order pressure parameters into the stack, the caller will pop up the stack parameters. The memory stack for routing parameters is maintained by the caller (because of this, the function that implements the mutable argument can only use the calling convention). In addition, there are differences in function name adornment conventions.

_cdecl are the default calling methods for C and C + + programs. Each function that calls it contains the code that empties the stack, so the resulting executable file size is larger than the call to the _stdcall function. The function uses a right-to-left compression stack. When a VC compiles a function, it will precede the function name with an underscore prefix. It is the MFC default calling convention.

3, __fastcall calling convention is "person" as its name, its main feature is fast, because it is through the register to transmit parameters (in fact, it uses ECX and EDX to transmit the first two double word (DWORD) or smaller parameters, the remaining parameters are still transferred from right to left to press the stack, The called function cleans the memory stack of the routing parameters before returning, and it differs from the previous two in terms of the function name adornment convention.

The function of the _fastcall method takes the register pass parameter, the VC compiles the function to precede the function name with the "@" prefix, after the function name adds "@" and the parameter the number of bytes.

4. ThisCall applies only to "C + +" member functions. 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.

5. When naked call uses 1-4 of the calling convention, if necessary, the compiler generates code to hold the ESI,EDI,EBX,EBP register when it enters the function, and the Exit function generates code to recover the contents of these registers.

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

The keywords __stdcall, __cdecl, and __fastcall can be directly added to the function to be exported, or they can be selected in the Setting...\c/c++ \code Generation item of the compilation environment. When the keyword before the output function is different from the selection in the compilation environment, the keyword directly before the output function is valid. Their corresponding command-line arguments are/gz,/gd, and/gr, respectively. The default state is/GD, which is __cdecl.

To completely imitate the PASCAL calling convention, you must first use the __stdcall calling convention, and as for the function name decoration conventions, you can imitate them by other means. Also worth mentioning is the WINAPI macro, which Windows.h supports the macro, which translates the function into the appropriate calling convention, which is defined as __stdcall in WIN32. Use the WINAPI macro to create your own APIs.

2) Name Decoration conventions

1. Decorated name (decoration name)

"C" or "C + +" functions are identified internally (compiled and linked) by decorated names. A decorated name is a string that the compiler generates when compiling a function definition or prototype. In some cases, it is necessary to use the decorated name of the function, such as specifying the output "C + +" overloaded functions, constructors, destructors in the module definition file, as well as calling "C" or "C + +" functions in the assembly code.

Decorated names are determined by the function name, class name, calling convention, return type, parameters, and so on.

2, the name adornment convention Tiaogan with the Convention and compiles the kind (c or C + +) the difference and changes. The function name Adornment convention differs depending on the type of compilation and the calling convention, as described below.

A, C compile-time function name adornment 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 [email protected].

The __cdecl calling convention only adds an underscore prefix to the output function name, in the form of _functionname.

The __fastcall calling convention adds an "@" symbol to the output function name, followed by an "@" symbol and the number of bytes of its parameter, in the format @[email protected].

They do not change the case of the character in the output function name, which differs from the Pascal calling convention in that the function name of the Pascal contract output is not decorated and capitalized.

b, c + + compile-time function name adornment Convention rules:

__stdcall calling convention:

1, with "?" Identifies the beginning of the function name followed by the name of the letter;

2, the function name after the "@ @YG" to identify the beginning of the parameter table, followed by the parameter table;

3, the parameter table is indicated by the code name:

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--represents the pointer, followed by the code indicates the pointer type, if the same type of pointer appears consecutively, with "0" instead of a "0" represents a repetition;

4. The first item of the parameter table 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, the parameter table after the "@z" to identify the end of the entire name, if the function has no parameters, the "Z" Mark to end.

The format is "[email protected] @YG *****@z" or "[email protected] @YG *xz",

For example

int Test1 (char *var1,unsigned long)-----"[Email protected]@[email protected]"
void Test2 ()-----"[Email protected] @YGXXZ"

__cdecl calling convention:

The rule is the same as the _stdcall calling convention above, except that the start identifier of the parameter table is changed from "@ @YG" to "@ @YA".

__fastcall calling convention:

The rule is the same as the _stdcall calling convention above, except that the start identifier of the parameter table is changed from "@ @YG" to "@ @YI".

VC + + On the function of the default declaration is "__CEDCL", will only be called by C + +.

Functions with respect to DLLs

There are two types of functions defined in a dynamic-link library: The export function and the intrinsic (internal function). The exported function can be called by other modules, and internal functions are used inside the DLL program that defines them.

There are several ways to output a function:

1, the traditional method

Specify the function or variable to be entered in the EXPORT section of the module definition file. The syntax format is as follows:

Entryname[=internalname] [@ordinal [NONAME]] [DATA] [PRIVATE]

which

EntryName is the output function or the name of the data being referenced;

InternalName with EntryName;

@ordinal indicates the sequential number (index) in the output table;

NONAME is only used when sequential numbers are output (do not use entryname);

Data indicates that the output is an item, and the program that uses the DLL to output data must declare the data item to be _DECLSPEC (DLLimport).

Of the above items, only the EntryName item is necessary, others can be omitted.

For the "C" function, EntryName can be equivalent to the function name, but for "C + +" functions (member functions, non-member functions), EntryName is the decorated name. You can get the decorated names of the functions to output from the. map image file, or use Dumpbin/symbols to get them and write them in the output module of the. def file. DUMPBIN is a tool provided by VC.

If you want to output a "C + +" class, write the data you want to output and the decorated names of the members to the. def module definition file.

2. Output at command line

Specify the/export command-line argument to the linker link, and output the function.

3. Using the modifier symbols provided by MFC _declspec (DLLexport)

The output is represented by the _declspec (DLLexport) modifier before the declaration of the function, class, and data to be exported. __declspec (DLLexport) can remove the underscore prefix for the output function name in the C-Call convention and C-compile case. extern "C" makes it possible to use C-compile in C + +. The definition of "C" functions under C + + requires the addition of extern "C" keywords. Use extern "C" to indicate that the function uses C compile mode. The output "C" function can be called from the "C" code.

For example, in a C + + file, you have the following function:

extern "C"

Its output function is named: Test

MFC provides a number of macros that have this effect.

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
AFX_EXT_API: #ifdef _afxext
Afx_api_export
#else
Afx_api_import
Afx_ext_data: #ifdef _afxext
Afx_data_export
#else
Afx_data_import

Macros such as AFX_EXT_CLASS, if used in the implementation of a DLL application, represent the output (because _afx_ext is defined, typically specified in the compiler's identity parameter/d_afx_ext), and if the application used to use the DLL represents an input (_ Afx_ext not defined).

To output the entire class, use _declspec (_dllexpot) for the class, and to output the member function of the class, use _declspec (_dllexport) for the function. Such as:

Class Afx_ext_class Ctextdoc:public CDocument
{
...
}
extern "C" Afx_ext_api void WINAPI initmydll ();

In these methods, it is best to use the third, convenient, followed by the first, if the order number output, the call efficiency will be higher;

module definition file (. DEF)

module definition file (. def) is a text file consisting of one or more module statements that describe the properties of a DLL, and each def file must contain at least the following module definition statements:

The first statement must be the library statement, indicating the name of the DLL;
The EXPORTS statement lists the name of the exported function, and the function decorated name to be output is listed under exports, which must exactly match the name of the defined function, so that a function name without any modification is obtained.
You can use the description statement to describe the purpose of the DLL (this sentence is optional);
";" Comment on a line (optional). The relationship between a DLL program and a 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 to the DLL can be used by the calling process, and the handle to the calling process can be used by the DLL.
DLL uses the stack that invokes the process.
2. About shared data segments

The global variables defined by the DLL can be accessed by the calling process, and the DLL can access the global data of the calling process. Each process that uses the same DLL has its own DLL global variable instance. If multiple threads access the same variable concurrently, you need to use the synchronization mechanism; For a DLL variable, you should use thread-local storage (Tls,thread local strorage) If you want each thread that uses the DLL to have its own value.

The purpose of setting the data segment properties is to include precompiled instructions in the program, or in the project settings of the development environment. These variables must be assigned an initial value, or the compiler will place a variable that does not have an initializer assigned to a data segment that is called uninitialized.

_stdcall, _cdecl,__fastcall in-depth analysis

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.