Function Calling Conventions and Name Decoration

今天在论坛上看到一位朋友问了一个如下的问题:


#define CALLBACK     __stdcall
#define WINAPI         __stdcall
#define WINAPIV       __cdecl
#define APIENTRY      WINAPI
#define APIPRIVATE   __stdcall
#define PASCAL         __stdcall

问题:
上面是这些宏的定义,但是不是很明白这些宏到底有什么用。 只是模模糊糊的知道这些关系到动态库的调用协议。


这位朋友提出的问题其实就是关于函数调用约定(Function Calling Convention)的问题。

为了搞清这个问题,最好的办法就是read MSDN !

From MSDN:


Calling Conventions

The Visual C/C++ compiler provides several different conventions for calling internal and external functions. Understanding these different approaches can help you debug your program and link your code with assembly-language routines.

The topics on this subject explain the differences between the calling conventions, how arguments are passed, and how values are returned by functions. They also discuss naked function calls, an advanced feature that enables you to write your own prolog and epilog code.

The following calling conventions are supported by the Visual C/C++ compiler.

vc calling conventions


__stdcall


Microsoft Specific
The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack, so the compiler makes vararg functions __cdecl. Functions that use this calling convention require a function prototype.
The following list shows the implementation of this calling convention.

__stdcall


__cdecl


Microsoft Specific
This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do

vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code.
The following list shows the implementation of this calling convention.

__cdecl


More details see MSDN  :)


我们初次在写Windows程序的时候都会先学习下面这个程序:

这里我们就会到看函数声明中有一个WINAPI宏,我们按F12后会发现其定义如下:
#define WINAPI __stdcall

调用约定(Calling convention):决定函数参数传送时入栈和出栈的顺序,栈内容由谁清除。缺省是__cdecl。

stdcall调用意味着:
1)参数从右向左压入堆栈。
2)函数自身维护堆栈,退出时清空堆栈。(cdecl由调用者清空堆栈,正因如此,实现可变参数的函数只能使用cdecl调用约定)

问题:
除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。但C/C++编译默认的是__cdecl约定。所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明时加上__stdcall修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)


下面是网上一位朋友总结的关于函数调用约定的文章,分析的很详细。我将其整理如下:
stems from:http://blog.vckbase.com/arong/archive/2004/06/09/409.html


欢迎对calling conventions有不同见解的朋友在此留言讨论!

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值