c/c++调用约定
2017-06-13 20:29
183 查看
C/C++函数调用约定
关于 C/C++
函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的。
VC
中默认调用是 __cdecl 方式,Windows API
使用 __stdcall 调用方式,在 DLL
导出函数中,为了跟 Windows API 保持一致,建议使用 __stdcall
方式。
调用约定跟堆栈清除密切相关。如果写一个汇编函数,给 C/C++
调用,在 __cdecl 方式下,则汇编函数无需清除堆栈,在 __stdcall
方式下,汇编函数需要在返回(RET)之前恢复堆栈。
C
语言有 __cdecl、__stdcall、__fastcall、naked、__pascal。
C++
语言有 __cdecl、__stdcall、__fastcall、naked、__pascal、__thiscall,比
C 语言多出一种 __thiscall 调用方式。
在VC中,可以设置默认的调用约定,设置路径为:
Project
à Properties
à Configuration Properties
à C/C++
à Advanced
à Call Conversion。
下面详细介绍如上六种调用方式:
1、__cdecl
__cdecl调用约定又称为 C
调用约定,是 C/C++ 语言缺省的调用约定。参数按照从右至左的方式入栈,函数本身不清理栈,此工作由调用者负责,返回值在EAX中。由于由调用者清理栈,所以允许可变参数函数存在,如int sprintf(char* buffer,const char* format,...);。
2、__stdcall
__stdcall
很多时候被称为 pascal 调用约定。pascal
语言是早期很常见的一种教学用计算机程序设计语言,其语法严谨。参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。
3、__fastcall
顾名思义,__fastcall
的特点就是快,因为它通过 CPU 寄存器来传递参数。他用 ECX
和 EDX 传送前两个双字(DWORD)或更小的参数,剩下的参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在 EAX
中。
4、naked
naked
是一个很少见的调用约定,一般不建议使用。编译器不会给这种函数增加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回结果,此调用约定必须跟 __declspec
同时使用。例如定义一个求和程序,如__declspec(naked) int
add(int a,int b);。
5、__pascal
这是 pascal
语言的调用约定,跟 __stdcall 一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。VC
中已经废弃了这种调用方式,因此在写 VC 程序时,建议使用 __stdcall
代替。
6、__thiscall
这是 C++
语言特有的一种调用方式,用于类成员函数的调用约定。如果参数确定,this 指针存放于 ECX
寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈。__thiscall
不是关键字,程序员不能使用。参数按照从右至左的方式入栈。
关于 C/C++
函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的。
VC
中默认调用是 __cdecl 方式,Windows API
使用 __stdcall 调用方式,在 DLL
导出函数中,为了跟 Windows API 保持一致,建议使用 __stdcall
方式。
调用约定跟堆栈清除密切相关。如果写一个汇编函数,给 C/C++
调用,在 __cdecl 方式下,则汇编函数无需清除堆栈,在 __stdcall
方式下,汇编函数需要在返回(RET)之前恢复堆栈。
C
语言有 __cdecl、__stdcall、__fastcall、naked、__pascal。
C++
语言有 __cdecl、__stdcall、__fastcall、naked、__pascal、__thiscall,比
C 语言多出一种 __thiscall 调用方式。
在VC中,可以设置默认的调用约定,设置路径为:
Project
à Properties
à Configuration Properties
à C/C++
à Advanced
à Call Conversion。
下面详细介绍如上六种调用方式:
1、__cdecl
__cdecl调用约定又称为 C
调用约定,是 C/C++ 语言缺省的调用约定。参数按照从右至左的方式入栈,函数本身不清理栈,此工作由调用者负责,返回值在EAX中。由于由调用者清理栈,所以允许可变参数函数存在,如int sprintf(char* buffer,const char* format,...);。
2、__stdcall
__stdcall
很多时候被称为 pascal 调用约定。pascal
语言是早期很常见的一种教学用计算机程序设计语言,其语法严谨。参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。
3、__fastcall
顾名思义,__fastcall
的特点就是快,因为它通过 CPU 寄存器来传递参数。他用 ECX
和 EDX 传送前两个双字(DWORD)或更小的参数,剩下的参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在 EAX
中。
4、naked
naked
是一个很少见的调用约定,一般不建议使用。编译器不会给这种函数增加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回结果,此调用约定必须跟 __declspec
同时使用。例如定义一个求和程序,如__declspec(naked) int
add(int a,int b);。
5、__pascal
这是 pascal
语言的调用约定,跟 __stdcall 一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。VC
中已经废弃了这种调用方式,因此在写 VC 程序时,建议使用 __stdcall
代替。
6、__thiscall
这是 C++
语言特有的一种调用方式,用于类成员函数的调用约定。如果参数确定,this 指针存放于 ECX
寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈。__thiscall
不是关键字,程序员不能使用。参数按照从右至左的方式入栈。
相关文章推荐
- C#调用C++ dll时CallingConvention调用约定详解
- C++调用约定和名字约定
- visual studio的C/C++修饰名及调用约定(如__cdecl)
- C/C++:函数的编译方式与调用约定以及extern “C”的使用
- C/C++中函数的调用约定(__cdecl, __stdcall)以及extern, extern “C"的详细解释
- C++调用约定和名字约定
- C++调用约定和名字约定
- 解读C++调用约定
- 【C++基础之五】函数调用机制与调用约定
- C/C++语言中的调用约定
- __declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定
- C++调用约定和名字约定
- C/C++中可变参数的原理 与函数调用约定
- C/C++:函数的编译方式与调用约定以及extern “C”的使用
- C/C++/动态链接库DLL中函数的调用约定与名称修饰
- C++调用约定和名字约定 thiscall
- 从华为面试来看C/C++的调用约定
- C/C++:函数的编译方式与调用约定以及extern “C”的使用
- C++调用约定和名字约定
- C/C++:函数的编译方式与调用约定以及extern “C”的使用