调用约定

调用约定(Calling
convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。

最常用的两种 Calling convention:

① _cdecl         

按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。  
  
如函数void    
test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是[email protected]@ZAXXZ。  
  
这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。

② _stdcall       

按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int
    func(int     a,     double    
b)的修饰名是[email protected]。对于“C++”函数,则有所不同。     
所有的Win32    
API函数都遵循该约定。


1 #define     CALLBACK     __stdcall
2 #define WINAPI __stdcall
3 #define WINAPIV __cdecl
4 #define APIENTRY WINAPI
5 #define APIPRIVATE __stdcall
6 #define PASCAL __stdcall

调用约定,布布扣,bubuko.com

时间: 2024-10-10 14:00:14

调用约定的相关文章

几种调用约定

调用约定(Callingconvention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法.MFC支持以下调用约定: 1._cdecl 按从右至左的顺序压参数入栈,由调用者把参数弹出栈.对于"C"函数或者变量,修饰名是在函数名前加下划线.对于"C++"函数,有所不同. 如函数voidtest(void)的修饰名是_test:对于不属于一个类的"C++"全局函数,修饰名是[email protecte

C# DllImport“调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ”

调用外部dll时,出现如下问题 C# DllImport“调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配.请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ” 后来经过仔细检查发现,误把vb中的longx型当成64位,实际上它相当于C#中的32位int型.

关于调用约定

__pascal 这是 pascal 语言的调用约定,跟 __stdcall 一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中.VC 中已经废弃了这种调用方式,因此在写 VC 程序时,建议使用 __stdcall 代替. __thiscall 这是 C++ 语言特有的一种调用方式,用于类成员函数的调用约定.如果参数确定,this 指针存放于 ECX 寄存器,函数自身清理堆栈:如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈.__thiscall 不是关键字,程

关于调用约定(cdecl、fastcall、、thiscall) 的一点知识(用汇编来解释)good

函数调用规范 当高级语言函数被编译成机器码时,有一个问题就必须解决:因为CPU没有办法知道一个函数调用需要多少个.什么样的参数.即计算机不知道怎么给这个函数传递参数,传递参数的工作必须由函数调用者和函数本身来协调.为此,计算机提供了一种被称为栈的数据结构来支持参数传递. 函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算.函数计算结束以后,或者调用者.或者函数本身修改堆栈,使堆栈恢复原装.在参数传递中,有两个很重要的问题必须得到明确说明: 1) 当参数个

DLL中调用约定和名称修饰(一)

DLL中调用约定和名称修饰(一) 调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议.这种协议规定了该语言的函数中的参数传送方式.参数是否可变和由谁来处理堆栈等问题.不同的语言定义了不同的调用约定. 在C++中,为了允许操作符重载和函数重载,C++编译器往往按照某种规则改写每一个入口点的符号名,以便允许同一个名字(具有不同的参数类型或者是不同的作用域)有多个用法,而不会打破现有的基于C的链接器.这项技术通常被称为名称改编(Name Manglin

调用约定CALLBACK

VC中涉及到调用约定的概念,特别是回调函数CALLBACK,WinAPI等. 这些其实都归结到调用约定上,VC中默认使用的时cdecl的C语言调用约定,而CALLBACK,WINAPI为stdcall即PASCAL调用约定.这两种约定在定义参数传递顺序及堆栈清楚方面有些差异.DELPHI采用的也是PASCAL约定,因此用DELPHI封装的函数在VC中调用时最好指定其约定是stdcall,否则容易造成程序崩溃. 同时,可以在IDE中设置工程默认使用的约定是stdcall还是cdecl.

64位只有一种调用约定stdcall

procedure TForm2.Button1Click(Sender: TObject); function EnumWindowsProc(Ahwnd: hwnd; AlParam: lParam): Boolean; stdcall; begin ShowMessage('hwnd:' + IntToStr(Ahwnd)); ShowMessage('lParam' + IntToStr(AlParam)); Result := True; end; begin EnumChildWin

在win64里,只有一种调用约定

在win64里,只有一种调用约定.以下是通过寄存器来传递4个整数类型的例子: *RCX:第一个参数 *RDX:第二个参数 *R8:第三个参数 *R9:第四个参数 参数里开头的4个整数会这样传给栈.传递浮点数参数时,使用的是XMMO-XMM3寄存器. 调用约定简化了:一律使用__fastcall,前四个参数用 RCX.RDX.R8 和 R9传递,除了这四个外加RAX.R10.R11,其他寄存器都是非易失的.

DLL-动态链接库(导入导出符/调用约定)

1. DLLs in Visual C++ 1.1 __declspec(llexport) and __declspec(dllimport) 首先,如题,这是VC的东西.*nix下不需要. 在VC中使用DLL的过程如下 1)新建一个Win32项目,右键项目→属性→常规,把配置属性改为dll,如图 2)在要导出(本工程外使用)的类.方法.变量之前,加上导出符号 __declspec(dllexport) [必须] 这就引出了本节的主角,先看微软的定义 You can import public