C基础下的函数调用技巧

C基础下的函数调用技巧

与函数堆栈使用密切相关的就是函数调用规范,即调用约定(Calling Convenion)。函数调用规范决定了函数调用的实参压栈、退栈及堆栈释放的方式以及函数名改编的方案,windows环境下常用的调用规范有:

1)      _cedcl:这是C++/C函数的默认调用规范,参数从右向左传递压入堆栈,由调用函数复杂堆栈的清退,因此这种方式利于传递个数可变的参数给被调用函数。如printf()就是这样的函数。

2)      _stdcall:这是Win API函数使用的调用规范,参数从右向左依次传递并压入堆栈,由被调用函数复杂堆栈的清退。该规范生成的函数代码比_cdecl更小,但当函数有可变个数的参数时会转为_cdecl规范。在Windows中,宏WINAPI、CALLBACK都定义为_stdcall。

3)      _thiscall:是C++非静态成员函数的默认调用规范,不能使用个数可变的参数。当调用非静态成员函数的时候,this指针直接保存在ECX寄存器中而压入函数堆栈,其他方面与_stdcall相同。

4)      _fastcall:该规范所修饰的函数的实参将被直接传递到CPU寄存器中而不是内存堆栈中,堆栈清退由被调用函数负责,该规范不能用于成员函数。

函数必须制定的一个调用规范,特别是在模块之间的逻辑接口中,每个函数原型的调用规范必须与其实的调用规范保持一致,否则会出现编译连接错误。如果你调用了在某个DLL中实现的COM对象的方法,而这些方法在创建时却没显式地制定调用规范,那么它们会使用环境默认的调用规范,虽然你的程序可以通过编译和连接,但是在运行时就可能导致程序崩溃。

所以,凡是接口函数都必须显式地制定其调用规范,除非接口函数是类的非静态成员函数,如果不显式制定调用规范,类的静态成员函数和全局函数将采用C++/C默认的函数调用规范或者由工程设置指定的调用规范,因此最好也为静态成员函数显式地指定调用规范。

注意:类的静态成员函数的默认调用规范不是thiscall,类的友元函数的调用也不是thiscall,它们都是由函数本身指定或者由工程设定的。COM接口的方法都指定_stdcall调用规范,而我们自己开发COM对象及接口时也可以指定其他的调用规范。

 

一定要知道C基础的基本概念:

 

认识函数堆栈:http://www.lirenedu.org/index.php?ack=xinwen&id=1026

基于C语言基础概念:http://www.lirenedu.org/index.php?ack=xinwen&id=1024

操作系统几个基本要点:http://www.lirenedu.org/index.php?ack=xinwen&id=1029

你可能感兴趣的:(C基础下的函数调用技巧)