__stdcall、__cdecl、CALLBACK、WINAPI区别

情景一:先看下Windows开发下的使用:

LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

这里就有一个CALLBACK,转到定义看一下

#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK    __stdcall
#define WINAPI      __stdcall
...

从上面也可以看到在windows平台下WINAPI和CALLBCAK其实是一致的;

情景二:另外我们知道在使用dumpbin DLL符号名的时候,假设有个add函数,输出时会如[email protected]@[email protected]之类的,如果加上extern ”C“之类的字符,输出的函数符号就是之前定义的add函数名了,这里就牵涉到函数调用问题,因为不同的语言和编译器平台,约定不一样,比如说函数的形参,默认采用的是压入栈中,有些是从左往右压入,有些则是从右往左压入的,不同的标准是不一样,所以如果调用就会出现出错,必须要指明哪一种调用方式,以便编译器能够正确识别。

那么他们有什么区别呢?

1)首先说下,C调用标准采用的是__cdecl,采用的入栈顺序,。。。

而Delphi采用的是pascal调用标准,即标准约定stdcall,也是Windows默认使用的约定,也就是说在Windows平台下WINAPI、CALLBCAK、stdcall其实都是一致的

2)__stdcall与__cdecl是两种不同的调用约定,定义了函数参数入栈的顺序,由调用函数还是被调用函数将参数弹出栈,以及产生函数修饰名的方法

3)在Windows程序中,回调函数必须遵从__stdcall调用约定,所以使用的是CALLBACK,当然也可以直接使用__stdcall,主要是便于区分

注意:有关入栈顺序,记得前面在看嵌入式方面的书籍中有关压入栈的顺序讲解较多,主要他们使用汇编,必须将具体的参数压入有关寄存器,然后取指的时候可以一一对应,回头查找一下,再做深入的解释

__stdcall、__cdecl、CALLBACK、WINAPI区别,布布扣,bubuko.com

时间: 2024-10-14 18:30:19

__stdcall、__cdecl、CALLBACK、WINAPI区别的相关文章

__stdcall,__cdecl,__fastcall的区别

__stdcall,__cdecl,__fastcall的区别 标签: dll编译器pascalclassimportinitialization 2009-12-09 15:07 10472人阅读 评论(1) 收藏 举报 分类: C/C++(22) __stdcall,__cdecl,__fastcall的区别 一.三者区别一览表 __stdcall __cdecl __fastcall 参数传递方式 右->左 压栈 右->左 压栈 左边开始的两个不大于4字节(DWORD)的参数分别放在EC

PASCAL==CALLBACK==WINAPI==__stdcall

VC里面:PASCAL==CALLBACK==WINAPI==__stdcall         _stdcall是Pascal程序的缺省调用方式,通常用于Win32  Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数.     _cdecl是C和C++程序的缺省调用方式.每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大.函数采用从右到左的压栈方式

js中callback.call()和callback()的区别

js中callback.call()和callback()的区别在js中callback.call()和callback() 有什么区别,举个例子:function a(){alert('hello!');}function b(callback){callback();}function c(callback){callback.call();}function test(){b(a);c(a);}在test函数中,b和c的效果是一样的,都执行了回调函数a.这两种用法有什么区别呢? -----

__stdcall __cdecl 引起的程序崩溃

崩溃弹出的截图如下 看到0xC0000005, 访问冲突的问题, 九成九是内存访问违规, 比如访问了已经释放的指针, 又或者是离开函数时栈被破坏之类. 找了一下午一直没有头绪, 好在有一份可以执行的源代码,  于是就将那份可执行的源代码改啊改,  改成和我的代码差不多的样子, 终于发现了问题 (我想,  这也算是查找问题的一种方式吧,  呵呵) 问题就出在了我使用的函数是__cdecl方式调用,  而要求传入的回调函数是要__stdcall调用,  结果出回调函数的时候就弹出了上面的那种对话框.

__declspec,__cdecl,__stdcall区别和作用

_cdecl和__stdcall都是函数调用规范(还有一个__fastcall),规定了参数出入栈的 顺序和方法,如果只用VC编程的话可以不用关心,但是要在C++和Pascal等其他语言通信的时候就要注意了,只有用相同的方法才能够调用成功.另外, 像printf这样接受可变个数参数的函数只有用cdecl才能够实现.      __declspec主要是用于说明DLL的引出函数的,在某些情况下用__declspec(dllexport)在DLL中生命引出函数,比用传统的 DEF文件方便一些.在普通

调用约定__cdecl和__stdcall

首先,__cdecl,c declaration,C风格声明.或者 c default calling(笔者瞎编的).(那么问题来了,为什么PASCAL风格被称为std?) 调用约定的内容包括三点:参数出入栈顺序,弹栈工作由谁做,以及产生函数名的方式(renaming?) 1. 在参数入栈顺序上,__cdecl和__stdcall没有区别都是从右往左: 2. __cdecl既然是c/c++默认,让我们回忆下下stl中的printf这样的变长参数函数,只有调用者才知道实参的情况,因此由调用者去负责

【转载】WINAPI宏

原文:http://blog.sina.com.cn/s/blog_3f27dee60100qi4j.html 一直搞不懂为什么在函数前面加上WINAPI.CALLBACK等是什么意思 又不是返回值 为什么加在前面 今天终于知道了 这是一个呼叫声明(姑且称之吧). 引子: 看看这个函数: int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw){     MSG msg; //进行程序的初始化工作 

C++ 小知识点 WINAPI

int WINAPI WINMain 中,WINAPI含义 网友给出回答:在windef.h头文件中有如下定义#define WINAPI      __stdcall#define APIENTRY    WINAPIVC有两种函数调用方式 一种是__stdcall,另一种是__cdecl函数的调用方式有两种一种是PASCAL调用方式,另一种是C调用方式使用PASCAL调用方式,函数在返回到调用者之前将参数从栈中删除使用C调用方式,参数的删除是调用者完成的WinMain函数是由系统调用的,Wi

lib和dll文件的区别和联系

什么是lib文件,lib和dll的关系如何 (2008-04-18 19:44:37)    (1)lib是编译时需要的,dll是运行时需要的. 如果要完成源代码的编译,有lib就够了. 如果也使动态连接的程序运行起来,有dll就够了. 在开发和调试阶段,当然最好都有. (2)一般的动态库程序有lib文件和dll文件.lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的.如果有 dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中.如果只有lib