惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

博客园 - Evilbaniry

(转)浏览器的两种模式quirks mode 和strict mode Does a Nodelist contain circle? XML Dom所有的节点类型 ExtJS-2.2内存泄漏补丁 (转)VC中#pragma warning指令 #define总结 (网上资料汇集) 自已为Ext添加的DateTimeField控件(附源码) VC里一些容易混淆的地方(转) (转)GetWindowLongPtr释义 (转)消息分流器 (转)std::map的用法总结 GetModuleFileName()得到程序路径 利用GetDriveType来得到驱动器信息 makeintresource:VC MAKEINTRESOURCE 析疑 (转)c/c++的预处理定义 Stringizing Operator (#) Charizing Operator (#@) Token-Pasting Operator (##) va_start() va_end()函数应用 #ifdef __cplusplus 倒底是什么意思? - Evilbaniry (转)typedef用法小结 判断windows系统类型
(转)STDAPI释义
Evilbaniry · 2008-12-24 · via 博客园 - Evilbaniry

对于一个初学者来说,对于如下函数定义,一定会有点迷惑。STDAPI DllGetClassObject(){}
也许你会问该函数定义中的STDAPI是什么东东。如果你对此迷惑,那我告诉你在WINNT.h文件中STDAPI宏定义如下:

#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
在MSDN中STDAPICALLTYPE宏有如下定义:

 1 #ifdef _WIN32 // Win32 doesn't support __export
 2   #define STDAPICALLTYPE __stdcall
 3 #else
 4   #define STDAPICALLTYPE __export __stdcall
 5 #endif
 6 
 7 #ifdef __cplusplus
 8   #define EXTERN_C extern "C"
 9 #else
10   #define EXTERN_C extern
11 #endif

由此可知,其实STDAPI只是一个宏定义。而该宏定义由两个宏定义(EXTERN_C和STDAPICALLTYPE)和HRESULT组成。经过预编译,有如下结果:
extern "c" HRESULT __stdcall  
这里,我假设是在Win32情况下进行预编译处理的,所以就没有__export了。同时,定义了__cplusplus,即用C++语法。
extern "C"就不用我来说明了吧。随便一本将c/c++的语法书都会提到的。HRESULT是函数的返回值类型。而__stdcall是一种调用类型(call type)。这才是我想说的东西。
在编程时,也许你会看到函数声明或定义中会出现CALLBACK和WINAPI两个宏。其实,它们也是__stdcall的代名词。看windef.h中的内容:

1 #define CALLBACK __stdcall
2 #define WINAPI __stdcall

那么,除了__stdcall,还有别的调用类型吗?究竟什么是调用类型呢?我的理解是:调用类型就是如何使用函数参数的一种规则。有三种调用类型:__fastcall、__cdecl、__stdcall。
1、__cdecl调用类型:
  这是C的调用规则。对于所有非C++成员函数或未标有__stdcall或__fastcall的函数来说,这是默认调用规则。
2、__fastcall调用类型:
  从字面意思可知,这是一种快速调用。因为CPU的寄存器会被使用来存放函数参数列表中的头几个参数。而剩下参数将被从右至左地推倒堆栈上。被调用函数将从寄存器和堆栈获得函数参数。在x86中,ECX和EDX一般被用来存放开始的参数。在.NET中,为了性能上的快速,就是使用ecx和edx来实现 __fastcall的。
3、 __stdcall调用类型:
  该调用只是通过堆栈来push和pop参数。push参数时,顺序是从右到左。

现在,你应该明白了吧。最后,我带一句。三种调用类型在VC编译器中对应/Gd、/Gr、/Gz三个编译选项。