C/C++:函数调用规则__stdcall,__cdecl,__pascal,__fastcall

__cdecl

__cdecl 是 C Declaration  的缩写,表示 C 语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

__stdcall

__stdcall 是 Standard Call 的缩写,是 C++ 的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是 this 指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的指令是 retnX,X 表示参数占用的字节数,CPU 在 ret 之后自动弹出 X 个字节的堆栈空间,称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。

__pascal

__pascal 是 Pascal 语言(Delphi)的函数调用方式,也可以在 C/C++ 中使用,参数压栈顺序与前两者相反。返回时的清栈方式与 __stdcall 相同。

__fastcall

__fastcall 是编译器指定的快速调用方式。由于大多数的函数参数个数很少,使用堆栈传递比较费时。因此 __fastcall 通常规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过堆栈传递。不同编译器编译的程序规定的寄存器不同,返回方式和 __stdcall 相当。

__thiscall

__thiscall 是为了解决类成员调用中 this 指针传递而规定的。__thiscall 要求把 this 指针放在特定寄存器中,该寄存器由编译器决定。VC 使用 ecx,Borland 的 C++ 编译器使用 eax。返回方式和 __stdcall 相当。
__fastcall 和 __thiscall 涉及的寄存器由编译器决定,因此不能用作跨编译器的接口。所以 Windows 上的 COM 对象接口都定义为 __stdcall 调用方式。

C 语言中不加说明默认函数为 __cdecl 方式(C中也只能用这种方式),C++ 也一样,但是默认的调用方式可以在 IDE 环境中设置。

时间: 2024-11-03 01:44:07

C/C++:函数调用规则__stdcall,__cdecl,__pascal,__fastcall的相关文章

__stdcall,__cdecl,__fastcall的区别

__stdcall,__cdecl,__fastcall的区别 标签: dll编译器pascalclassimportinitialization 2009-12-09 15:07 10472人阅读 评论(1) 收藏 举报 分类: C/C++(22) __stdcall,__cdecl,__fastcall的区别 一.三者区别一览表 __stdcall __cdecl __fastcall 参数传递方式 右->左 压栈 右->左 压栈 左边开始的两个不大于4字节(DWORD)的参数分别放在EC

JavaScript函数调用规则

1. [代码][JavaScript]代码     JavaScript函数调用规则一 (1)全局函数调用:function makeArray( arg1, arg2 ){    return [this , arg1 , arg2 ];}这是一个最常用的定义函数方式.相信学习JavaScript的人对它的调用并不陌生.调用代码如下:makeArray('one', 'two');// => [ window, 'one', 'two' ] 这种方式可以说是全局的函数调用.为什么说是全局的函数

__stdcall __cdecl 引起的程序崩溃

崩溃弹出的截图如下 看到0xC0000005, 访问冲突的问题, 九成九是内存访问违规, 比如访问了已经释放的指针, 又或者是离开函数时栈被破坏之类. 找了一下午一直没有头绪, 好在有一份可以执行的源代码,  于是就将那份可执行的源代码改啊改,  改成和我的代码差不多的样子, 终于发现了问题 (我想,  这也算是查找问题的一种方式吧,  呵呵) 问题就出在了我使用的函数是__cdecl方式调用,  而要求传入的回调函数是要__stdcall调用,  结果出回调函数的时候就弹出了上面的那种对话框.

Swift 2.0学习笔记(Day 42)——构造函数调用规则

原创文章,欢迎转载.转载请注明:关东升的博客 在构造函数中可以使用构造函数代理帮助完成部分构造工作.类构造函数代理分为横向代理和向上代理,横向代理只能在发生在同一类内部,这种构造函数称为便利构造函数.向上代理发生在继承的情况下,在子类构造过程中,要先调用父类构造函数初始化父类的存储属性,这种构造函数称为指定构造函数. 构造函数调用规则 Person和Student类示例: class Person { var name: String var age: Int func description(

《从零开始学Swift》学习笔记(Day 42)——构造函数调用规则

原创文章,欢迎转载.转载请注明:关东升的博客 在构造函数中可以使用构造函数代理帮助完成部分构造工作.类构造函数代理分为横向代理和向上代理,横向代理只能在发生在同一类内部,这种构造函数称为便利构造函数.向上代理发生在继承的情况下,在子类构造过程中,要先调用父类构造函数初始化父类的存储属性,这种构造函数称为指定构造函数. 构造函数调用规则 Person和Student类示例: class Person {     var name: String     var age: Int          

函数调用方式__stdcall、__cdel

函数调用方式关系对比如下: 关键字 调用规则 参数传递方向 返回 参数寄存器 堆栈的清除 __cdecl C语言 从右向左 EAX 无 调用者 __stdcall Win32标准  从右向左 EAX 无 被调用者 __fastcall 寄存器 从左向右 EAX EAX.EBX.ECX 被调用者 __pascal Pascal 从左向右 EAX 无 被调用者 __msfastcall Ms寄存器 从右向左  EAX/EDX ECX.EDX 被调用者

函数调用方法之__cdecl与_stdcall

在debug VS c工程文件时,碰到cannot convert from 'int (__cdecl *)(char *)' to 'xxx'这个问题,发现问题在于typedef函数指针类型时,将函数调用方法__cdecl写成了_stdcall. 后来百度了两者的区别,如下: __cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈.被调用函数不会要求调用者传递多少参数,调用

构造函数调用规则

首先我们知道只要创建一个类编译器会提供三个默认函数 1.默认构造函数 (无参,空实现) 2.默认析构函数(无参,空实现) 3.默认拷贝构造函数,对值属性进行拷贝 调用规则如下 1.如果我们定义有参构造函数,编译器不会提供默认构造函数,但提供默认拷贝构造函数 2.如果用户定义了拷贝构造函数,编译器将不会提供其他构造函数 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 class person 5 { 6 public: 7 person(

WIN7+VS2010 制作与调用DLL

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 嗯哼~之前帮老师做的那个模块,不用做了=  =. 做了近十天,结果跑了13分钟 人家,秒级别的,甚至毫秒级的速度.... 哎.... 跪拜ING,2000+ X 2000+阶矩阵,有乘法,点乘,转置,求逆,一系列操作, 而且,乘法至少要进行40+次,求逆也要进行