`
fireDragonpzy
  • 浏览: 463087 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

几种函数调用方式

c++ 
阅读更多

几种函数调用方式

  __cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。
  _stdcall 是StandardCall的缩写,是C++的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的指令是 retnX,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。
  PASCAL 是Pascal语言的函数调用方式,也可以在C/C++中使用,参数压栈顺序与前两者相反。返回时的清栈方式与_stdcall相同。
  _fastcall是编译器指定的快速调用方式。由于大多数的函数参数个数很少,使用堆栈传递比较费时。因此_fastcall通常规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过堆栈传递。不同编译器编译的程序规定的寄存器不同。返回方式和_stdcall相当。
  _thiscall 是为了解决类成员调用中this指针传递而规定的。_thiscall要求把this指针放在特定寄存器中,该寄存器由编译器决定。VC使用ecx,Borland的C++编译器使用eax。返回方式和_stdcall相当。
  _fastcall 和 _thiscall涉及的寄存器由编译器决定,因此不能用作跨编译器的接口。所以Windows上的COM对象接口都定义为_stdcall调用方式。
  C中不加说明默认函数为_cdecl方式(C中也只能用这种方式),C++也一样,但是默认的调用方式可以在IDE环境中设置。
  带有可变参数的函数必须且只能使用_cdecl方式,例如下面的函数:
  int printf(char * fmtStr, ...);
  int scanf(char * fmtStr, ...);
  */几种调用约定的区别
编辑本段
几种调用约定的区别

  __cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数弹出栈,3)以及产生函数修饰名的方法。
  1、__stdcall调用约定:函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,
  2、_cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。注意:对于可变参数的成员函数,始终使用__cdecl的转换方式。
  3、__fastcall调用约定:它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)。
  4、thiscall仅仅应用于"C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。
  5、nakedcall采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。
编辑本段
名字修饰约定

  1、修饰名(Decoration name):"C"或者"C++"函数在内部(编译和链接)通过修饰名识别
  2、C编译时函数名修饰约定规则:
  __stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个"@"符号和其参数的字节数,格式为_functionname@number,例如 :function(int a, int b),其修饰名为:_function@8
  __cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_functionname。
  __fastcall调用约定在输出函数名前加上一个"@"符号,后面也是一个"@"符号和其参数的字节数,格式为@functionname@number。
编辑本段
设置方法

  1 可以直接在代码中写 __cdecl 等调用约定
  2 在MS-VC++6.0中,调用约定也可以通过工程设置:Setting...\C/C++ \Code Generation项进行选择,缺省状态为__cdecl。名字修饰约定。


摘自:http://baike.baidu.com/view/1280676.htm
分享到:
评论

相关推荐

    几种函数调用方式 asm ,disassemble

    几种函数调用的方式,关于函数调用的一些东西,选自 Hacker Disassembling Uncovered 里的一节 ,精简版..

    c/c++中函数调用方式

    根据给定的文件信息,我们可以深入探讨C/C++中几种主要的函数调用方式:__cdecl、__stdcall和__fastcall,以及C++特有的thiscall。 ### __cdecl `__cdecl`,即“C声明”或“C default”,是C/C++中默认的调用约定...

    visual c++中函数调用方式浅探

    ### Visual C++中函数调用方式浅探 在Visual C++环境下进行软件开发时,了解不同的函数调用约定(calling conventions)对于优化程序性能、理解编译器行为以及避免潜在的错误至关重要。本文将深入探讨Visual C++中...

    C/C++函数调用的几种方式总结

    本文将详细讲解C/C++中常见的几种函数调用方式,包括stdcall、cdecl、fastcall、thiscall以及naked call。 1. stdcall调用方式: stdcall,也称为Pascal调用方式,主要用于Windows API函数。在stdcall中,参数按从...

    C++中的类中函数调用

    类中函数调用通常涉及以下几种情况: 1. **非静态成员函数调用**:这是最常见的函数调用形式,需要通过类的实例(对象)来调用,因为这些函数可能访问或修改类的私有或保护成员。 2. **静态成员函数调用**:静态...

    函数的几种调用机制

    文档中提到了几种常见的调用约定: 1. stdcall调用约定:也被称为pascal调用约定,Microsoft C++系列编译器中常用。其特点是参数从右向左压栈,函数自己负责清理堆栈。函数名经过特定的命名修饰,通常在函数名前加...

    C++箴言:避免析构函数调用虚函数

    ### C++箴言:避免析构函数调用虚函数 #### 概述 在C++编程中,理解和遵循良好的设计模式对于确保程序的稳定性和可维护性至关重要。其中一个经常被提及的原则是“避免在析构函数中调用虚函数”。这一原则在C++语言...

    动态函数调用追踪方法

    这通常通过以下几种方式实现: 1. **预编译插桩(Bytecode instrumentation)**:利用Java代理(Java Agent)或者ASM、ByteBuddy等库修改字节码,在函数调用前后插入记录代码。 2. **运行时拦截(Runtime ...

    DLL创建与函数调用规则

    首先,DLL分为几种类型: 1. Non-MFC DLL:这类DLL不依赖于MFC(Microsoft Foundation Classes)库,而是直接使用C语言编写,输出的函数通常采用标准C接口,因此可以被非MFC或MFC应用调用。它们的函数声明通常使用`...

    matlab自定义函数调用的方法

    以下是关于MATLAB自定义函数调用的五种方法的详细说明: 1. **命令/函数文件 + 函数文件**: 在这种方法中,自定义函数被编写在一个独立的`.m`文件中,例如`mylfg.m`。函数名与文件名相同,如`function y = mylfg...

    API函数调用 windows编程

    在Windows编程中,有几种常见的API调用方式: 1. **直接调用**:直接在代码中使用函数声明和调用,例如: ```c++ #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, ...

    常用的函数调用约定的比较

    本文将详细探讨几种常见的函数调用约定,包括`__stdcall`、`__cdecl`、`__fastcall`等,并分析它们的特点和适用场景。 #### 一、__stdcall 调用约定 `__stdcall`调用约定,又称为PASCAL调用约定,在32位VC++5.0中...

    2函数的调用教案——高校教师资格证教案.docx

    根据函数调用在程序中的位置和作用,有三种调用方式:1) 函数调用语句,独立于其他语句,不关心函数是否返回值,例如`printf("%d",a)`;2) 函数表达式,函数调用作为另一个表达式的一部分,如`c=max(a,b)`;3) 函数...

    函数直接调用几种方法_loki_grandmotherxmb_函数直接调用_元编程_

    在标题"函数直接调用几种方法_loki_grandmotherxmb_函数直接调用_元编程_"中,我们看到了几个关键概念:函数直接调用、洛基库(Loki)、元编程以及"grandmotherxmb",这可能是一个特定的代码示例或库的作者名称。...

    计算递归函数调用次数

    在编程领域,递归函数是一种强大的工具...总的来说,理解和计算递归函数调用次数是编程中的重要技能,它涉及到算法分析、性能优化和问题解决策略等多个方面。通过熟练掌握递归,程序员能更好地应对各种复杂的编程挑战。

    C语言函数调用汇编语言函数[归纳].pdf

    C语言函数调用汇编语言函数是软件开发中的一种常见技术。本文将对C语言函数调用汇编语言函数进行总结,详细介绍相关知识点。 一、C语言函数调用汇编语言函数的定义 C语言函数调用汇编语言函数是指在C语言程序中...

    Matlab函数的几种定义方式

    以下将详细介绍标题和描述中提到的七种函数定义方法: 1. **函数文件+调用命令文件**: 在这种定义方式下,我们需要创建一个`.m`文件,比如`my_sum.m`,其中包含自定义函数的代码。例如,为了实现一个求和功能,...

    C语言教学中函数调用问题探讨.pdf

    综上所述,C语言的教学过程中,函数调用问题的探讨涵盖了函数定义、函数调用方式、库函数调用以及函数调用在实际问题中的应用等多个方面。通过教学案例的分析和教学方法的探讨,可以更有效地帮助学生掌握函数调用的...

Global site tag (gtag.js) - Google Analytics