从WINAPI和CALLBACK这两个宏说开去- -(转)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

WINAPI和CALLBACK这两个宏有什么区别呢?

_stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢?

首先看MSDN里给出的解释,不过有些语焉不详哦

WINAPI
·Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported API entry points, you can use this for your own APIs.

CALLBACK
·Use in place of FAR PASCAL in application callback routines such as window procedures and dialog procedures.

再看看到底这两个宏的内容是什么吧

VC:WINDEF.h
#define CALLBACK    PASCAL //=_pascal,VC已经不支持直接使用_pascal了
#define WINAPI      CDECL //=_cdecl

BCB:windef.h
#define CALLBACK    __stdcall
#define WINAPI      __stdcall

引出了cdecl stdcall等一些可能很少见的关键字

那么cdecl、pascal、stdcall、fastcall等修饰符号到底什么意思呢?
非常简单,就是关于堆栈的一些说明,首先是函数参数压栈顺序,其次是
压入堆栈的内容由谁来清除,调用者还是函数自己?
这些开关用来告诉编译器产生什么样的汇编代码。

下面把区别列表如下:

Directive Parameter order  Clean-up Passes parameters in registers?
register  Left-to-right   Routine   Yes
pascal   Left-to-right   Routine   No
cdecl   Right-to-left   Caller    No
stdcall   Right-to-left   Routine   No
safecall  Right-to-left   Routine   No

简单说明:

__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时, 函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl 约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。
        __stdcall调用约定用于调用Win32 API函数。采用__stdcal约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知 道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。
        __fastcall约定用于对性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放 在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall。

·特别说明
1. 在默认情况下,采用__cdecl方式,因此可以省略.
2. WINAPI一般用于修饰动态链接库中导出函数
3. CALLBACK仅用于修饰回调函数
4. 你可能已经发现,VC下和BCB下对WINAPI的定义不同,那么你至少理解了
   为什么不能直接从BCB下调用VC的dll的一个原因了。

另附CSDN上高手回答,觉得比较有道理:

在windef.h头文件中有如下定义  
#define   WINAPI             __stdcall  
#define   APIENTRY         WINAPI  
VC有两种函数调用方式   一种是__stdcall,另一种是__cdecl  
函数的调用方式有两种一种是PASCAL调用方式,另一种是C调用方式  
使用PASCAL调用方式,函数在返回到调用者之前将参数从栈中删除  
使用C调用方式,参数的删除是调用者完成的  
WinMain函数是由系统调用的,Windows系统规定由系统调用的函数都遵守PASCAL调用方式  
但是VC中函数的缺省调用方式是__cdecl,也就是C调用方式  
所以在WinMain前显示的声明。  
在Windows编程中将遇到很多声明修饰符,如CALLBACK,WINAPI,PASCAL这些在IntelCPU的计算机上都是__stdcall  
详细的声明细节请看windef.h文件  

Windows API函数中文版完整使用指南 本文还有配套的精品资源,点击获取 简介:这份资源为开发者提供了一份详尽的API函数中文版大全,涵盖了Windows编程中常用的API函数,方便中文用户理解应用。虽不是API大全的完整集合,但提供了系统调用、图形界面、文件处理网络通信等方面的函数,帮助初学者非英语母语者快速学习解决问题。用户可通过CHM格式的帮助文件查找API函数的用法、参数、返回值示例。 ... 阅读详情

相关推荐

Windows API函数实战详解

本文还有配套的精品资源,点击获取 简介:Windows API作为微软Windows操作系统的核心接口,提供了丰富的函数库供开发者与操作系统交互。本压缩包文件“win32api.chm”包含详细的API函数说明,旨在帮助开发者深入理解并运用这些函数来创建界面、处理消息、绘制图形、进行网络通信内存管理等。掌握Windows API是进行Windows平台软件开发的重要环节,...

weixin_42376614的博客 1667

Windows API函数大全(精心总结)_winapi函数大全

RemoveDirectory删除指定目录SearchPath查找指定文件SetCurrentDirectory设置当前目录SetEndOfFile针对一个打开的文件,将当前文件位置设为文件末尾SetFileAttributes设置文件属性SetFilePointer在一个文件中设置当前的读写位置SetFileTime设置文件的创建、访问及上次修改时间SetHandleCount这个函数不必在win32下使用;即使使用,也不会有任何效果。

2401_84447233的博客 3783

Windows API编程01-详解第一个程序(超级详细)

简单介绍Windows API:Windows API(Application Programming Interface)是Microsoft Windows平台的应用程序编程接口,其主要目的是让应用程序开发人员可以调用操作系统提供的一组例程功能,而无须考虑其底层的源代码实现及内部工作机制。API函数是构筑整个Windows框架的基石,它基于Windows的操作系统核心,上层是所有的Windows应用程序。简单来说,这些API接口就是函数,就像C语言调用的stdio.h中的函数一样。

smiler_D的博客 9492

Windows Api 学习笔记 1——基础知识(上)

Windows Api 学习笔记 1——基础知识(上)

JCY的博客 2595

()WINAPICALLBACK两个说开- -

从bbs上看到有同学问这个问题,因此回答了这个帖子。 WINAPICALLBACK两个有什么区别呢?_stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢? 首先看MSDN里给出的解释,不过有些语焉不详哦WINAPI ·Use in place of FAR PASCAL in API declarations

lacsis的专栏 523

WINAPICALLBACK两个有什么区别呢?

<br />WINAPICALLBACK两个有什么区别呢?<br /><br />_stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢?<br /><br /><br />首先看MSDN里给出的解释,不过有些语焉不详哦<br /><br />WINAPI <br />·Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported API ent

Dolly2012的专栏 712

WINAPICALLBACK

intWINAPIWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd  );《windows 程序设计》对WINAPI的解释为:WINAPI识别字在WINDEF.H定义,语句如下:#define WINAPI __stdcall该语句指定了一个呼叫约定,包括如何生产机械码以在堆叠中

Y·F·C 2553

WINAPICALLBACK的区别

WINAPICALLBACK的区别[] _stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢? 首先看MSDN里给出的解释,不过有些语焉不详哦WINAPI ·Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported A...

aixi8485的博客 424

WINAPI

一直搞不懂为什么在函数前面加上WINAPICALLBACK等是什么意思 又不是返回值 为什么加在前面 今天终于知道了 这是一个呼叫声明(姑且称之吧)。 引子: 看看这个函数: int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {      MSG msg;    

slj_win的专栏 2361

MFC中CALLBACK,WINAPI的区别联系

首先看MSDN里给出的解释,不过有些语焉不详哦 WINAPI ·Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported API entry points, you can use this for your own APIs. CALLBACK ·Use in place of F

叮叮福 872

WINAPICALLBACK两个说开

从bbs上看到有同学问这个问题,因此回答了这个帖子。 WINAPICALLBACK两个有什么区别呢?_stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢? 首先看MSDN里给出的解释,不过有些语焉不详哦WINAPI ·Use in place of FAR PASCAL in API declarations. If y

183

WINAPICALLBACK两个有什么区别

stdcall  _cdecl  _pascal  _fastcall这些关键字是什么意思,有什么区别呢? 首先看MSDN里给出的解释,不过有些语焉不详哦 WINAPI ·Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported API entry points, you can u

Kevin's Blog 1027

MFC中CALLBACK函数 WINAPI函数的区别

凡是由你设计却由windows系统呼叫的函数,统称为callback函数。某些API函数要求以callback作为你参数之一。如SetTimer,LineDDA,EnumObjects。   回调函数是由开发者按照一定的原形进行定义的函数(每个回调函数都必须遵循这个原则来设计)  例如:  ----------------------------------------   BOOL CALL

wangjiechen的博客 1218

WINAPICALLBACK两个【zt】

WINAPICALLBACK两个 WINAPICALLBACK两个有什么区别呢? _stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢? 首先看MSDN里给出的解释,不过有些语焉不详哦 WINAPI ·Use in place of FAR PASCAL in API declarations. If you are writing 

眼界决定世界 奋斗成就梦想 695

WINAPICALLBACK两个有什么区别呢?还关于stdcallcdecl的区别

结果对于我这样一个普通程序员,估计那么点开销,不会关注!关于需要Dll导出的class,需要加特别的API的。 WINAPICALLBACK两个 _stdcall _cdecl _pascal _fastcall这些关键字是什么意思,有什么区别呢? 首先看MSDN里给出的解释,不过有些语焉不详哦WINAPI ·Use in place of FAR PASCA

sh_chenjian的专栏 1069

C++ CALLBACKWINAPI两个的含义?

在编程时,也许你会看到函数声明或定义中会出现CALLBACKWINAPI两个。其实,它们也是__stdcall的代名词。看windef.h中的内容: #define CALLBACK __stdcall #define WINAPI __stdcall __stdcall是调用类型.调用类型有:__fastcall、__cdecl、_...

weixin_34233421的博客 561
上一篇: CSocket如何从CAsyncSocket变成同步
下一篇: CloseHandle()函数的使用
FlowShell
博客等级 码龄17年 119粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值